3

私はこれができることを知っています:

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

IDateTimeFactory.NowがプロパティではなくメソッドIDateTimeFactory.GetNow()である場合、どうすれば同じことを行うことができますか?

以下のユダの提案に従って、 SetDateTime ヘルパーメソッドを次のように書き直しました。

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

しかし、それでも「ICurrentDateTimeFactory.GetNow(); の結果は既にセットアップされています」がスローされます。エラー。

さらに、スタブではまだ機能しません....

4

4 に答える 4

7

これは古い質問であることは知っていますが、最新の Rhino Mocks バージョンの更新を投稿すると思いました。

Do() を使用する以前の回答に基づいて、Rhino Mocks (バージョン 3.5+ から利用可能) で AAA を使用している場合、利用可能な少しクリーンな (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());
    }
于 2011-02-05T00:29:08.740 に答える
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、スタブを使用してこれを達成できるとは思いません。代わりにモックを使用する必要があります。

于 2008-09-23T21:54:55.517 に答える
0

GetSomething は複数回呼び出される可能性があり、その回数がわからないため、私の最初の答えはうまくいきません。

ここで複雑なシナリオに入ります-メソッド呼び出しの数は不明ですが、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);
}
于 2008-09-23T20:43:25.877 に答える
0

これを実現するには、Expect.Call を使用できます。記録/再生モデルを使用した例を次に示します。

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);
}
于 2008-09-23T20:07:19.927 に答える