2008-09-23 5 views
2

는 내가이 작업을 수행 할 수 있습니다 알고있는 스텁 방법에 대한 새로운 결과를 할당 할 재 :코뿔소 모의 객체 :

대신 IDateTimeFactory.Now가 속성 인 경우이 방법 IDateTimeFactory는 무엇
IDateTimeFactory dtf = MockRepository.GenerateStub<IDateTimeFactory>(); 
dtf.Now = new DateTime(); 
DoStuff(dtf); // dtf.Now can be called arbitrary number of times, will always return the same value 
dtf.Now = new DateTime()+new TimeSpan(0,1,0); // 1 minute later 
DoStuff(dtf); //ditto from above 

.GetNow(), 어떻게 같은 일을합니까? 유다의 제안 사항에 따라

다음과 같이 내 SetDateTime 도우미 방법을 다시 한 아래 :

private void SetDateTime(DateTime dt) { 
     Expect.Call(_now_factory.GetNow()).Repeat.Any(); 
     LastCall.Do((Func<DateTime>)delegate() { return dt; }); 
    } 

을하지만 여전히 발생 "ICurrentDateTimeFactory.GetNow()의 결과는, 이미 설치되었습니다." 오류.

플러스는 여전히 당신은 이러한 목표를 달성하기 위해 Expect.Call을 사용할 수 있습니다

답변

1

조지,

가 업데이트 된 코드를 사용하여, 나는이 일을하는 데 :

MockRepository mocks = new MockRepository(); 

[Test] 
public void Test() 
{ 
    IDateTimeFactory dtf = mocks.DynamicMock<IDateTimeFactory>(); 

    DateTime desiredNowTime = DateTime.Now; 
    using (mocks.Record()) 
    { 
     SetupResult.For(dtf.GetNow()).Do((Func<DateTime>)delegate { return desiredNowTime; }); 
    } 
    using (mocks.Playback()) 
    { 
     DoStuff(dtf); // Prints the current time  
     desiredNowTime += TimeSpan.FromMinutes(1); // 1 minute later  
     DoStuff(dtf); // Prints the time 1 minute from now 
    } 
} 

void DoStuff(IDateTimeFactory factory) 
{ 
    DateTime time = factory.GetNow(); 
    Console.WriteLine(time); 
} 

FWIW, 당신이 스텁을 사용하여 이것을 수행 할 수 있다고 생각하지 않습니다; 대신 모의 (mock)를 사용해야합니다.

+0

당신의 도움에 감사합니다 유다 –

+0

그것이 당신을 위해 일해 주어 기쁘다! FWIW, 나는이 포스트에 관해 Ayende에게 이메일을 보냈다. 그는 내가하는 것보다 더 나은 대답을 할 수도 있습니다. –

+1

George, Ayende는 이러한 해답을 보았습니다. 그는 우리가 Closure를 사용하고 Expect.Call (...) 대신 SetupResult.For를 사용할 수 있다고 말했다. Repeat.Any(). 그렇지 않으면 그는이 대답에 반대하지 않았습니다. –

0

.... 그루터기와 함께 작동하지 않을. 다음은 녹음/재생 모델을 사용하는 예는 다음과 같습니다 GetSomething 여러 번 호출 할 수 있기 때문에

using (mocks.Record()) 
{ 
    Expect.Call(s.GetSomething()).Return("ABC"); // 1st call will return ABC 
    Expect.Call(s.GetSomething()).Return("XYZ"); // 2nd call will return XYZ 
} 
using (mocks.Playback()) 
{ 
    DoStuff(s); 
    DoStuff(s); 
} 
+0

그래,하지만이 방법은 DoStuff() 내에서 한 번 스터브 된 메서드를 호출 할 때만 해당 결과를 항상 속성과 동일하게 반환하려는 경우에만 적용됩니다. . Repeat()를 사용할 수는 있지만 무시할 수는 없다고 생각합니다. –

+0

플러스 나는 스텁과 함께 작동하지 않는다고 생각합니다. –

+0

조지, 알았어요. 당신이 이것을 달성 할 수있는 방법에 대한 새로운 답을 쓸 것입니다. –

0

좋아, 그래서 내 첫 번째 대답은 당신을 위해 작동하지 않습니다, 당신은 얼마나 많은 시간을 모르겠어요.

DoSomething이 호출 된 후에도 알 수없는 메소드 호출 수가 있지만 아직 다른 결과가 있습니다. 더 간단하도록 단위 테스트를 해체 할 것을 권장합니다. 그렇지 않으면 유닛을 가져야합니다. 당신의 단위 테스트를위한 테스트. :-)

가 실패, 여기 당신이 뭘 하려는지 달성 할 수있는 방법은 다음과 같습니다

bool shouldReturnABC = true; 
using (mocks.Record()) 
{ 
    Expect.Call(s.GetSomething()).Repeat.Any(); 

    LastCall.Do((Func<string>)delegate() 
    { 
     return shouldReturnABC ? "ABC" : "XYZ"; 
    } 
} 
using (mocks.Playback()) 
{ 
    DoStuff(s); 
    shouldReturnABC = false; 
    DoStuff(s); 
} 
+0

그 복잡하지, 나는 GetTime (GetNow()를 가진 IDateTimeNowFactory가있다 그래서 나는 DateTime.Now 조롱하고있다; 나는 그것을 뛰어 넘기 위해 말할 때까지 같은 값을 돌려주고 싶습니다. 나는 이것이 너무 뾰족한 경우라고 상상하지 않는다. 스텁 속성과 같은 것이지만 방법은 –

+0

이다. 내 대답이 당신의 문제를 해결 했습니까? 나는 그것을 여기에서 시험했고 그것은 올바르게 작동하는 것처럼 보였다. –

+0

이상하게도 충분히, 아니, 여전히 결과가 이미 설정되어 있다고 말하면 내 질문을 업데이트하여 실제 코드에 가깝게합니다. –

6

저는 이것이 오래된 질문이지만 더 최근의 Rhino Mocks 버전에 대한 업데이트를 게시 할 것이라고 생각했습니다.

Do()를 사용하는 이전 답변을 바탕으로 AAA in Rhino Mocks (버전 3.5 이상에서 사용 가능)을 사용하는 경우 사용할 수있는 약간 더 깨끗한 (IMO) 방법이 있습니다.

[Test] 
    public void TestDoStuff() 
    { 
     var now = DateTime.Now; 
     var dtf = MockRepository.GenerateStub<IDateTimeFactory>(); 
     dtf 
      .Stub(x => x.GetNow()) 
      .Return(default(DateTime)) //need to set a dummy return value 
      .WhenCalled(x => x.ReturnValue = now); //close over the now variable 

     DoStuff(dtf); // dtf.Now can be called arbitrary number of times, will always return the same value 
     now = now + new TimeSpan(0, 1, 0); // 1 minute later 
     DoStuff(dtf); //ditto from above 
    } 

    private void DoStuff(IDateTimeFactory dtf) 
    { 
     Console.WriteLine(dtf.GetNow()); 
    } 
관련 문제