28

メソッドが 1 回だけ呼び出されると主張したい。RhinoMocks 3.5 を使用しています。

これが私がうまくいくと思ったものです:

[Test]
public void just_once()
{
    var key = "id_of_something";

    var source = MockRepository.GenerateStub<ISomeDataSource>();
    source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
        .Return(new Something())
        .Repeat.Once();

    var client = new Client(soure);

    // the first call I expect the client to use the source
    client.GetMeMyThing(key);

    // the second call the result should be cached
    // and source is not used
    client.GetMeMyThing(key);
}

GetMeMyThing()2 回目の呼び出しでこのテストが失敗するようにしますsource.GetSomethingThatTakesALotOfResources()

4

7 に答える 7

34

メソッドが一度呼び出されたことを確認する方法は次のとおりです。

[Test]
public void just_once()
{
    // Arrange (Important to GenerateMock not GenerateStub)
    var a = MockRepository.GenerateMock<ISomeDataSource>();
    a.Expect(x => x.GetSomethingThatTakesALotOfResources()).Return(new Something()).Repeat.Once();

    // Act
    // First invocation should call GetSomethingThatTakesALotOfResources
    a.GetMeMyThing();

    // Second invocation should return cached result
    a.GetMeMyThing();

    // Assert
    a.VerifyAllExpectations();
}
于 2009-02-20T05:54:22.463 に答える
16

私はこの問題を回避するためにAssertWasCalled拡張機能を使用しています。これは私が見つけたり思いついたりするのに最適ですが、呼び出しを2回指定する必要がない方がよいでしょう。

    [Test]
    public void just_once()
    {
        var key = "id_of_something";

        var source = MockRepository.GenerateStub<ISomeDataSource>();

        // set a positive expectation
        source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
            .Return(new Something())
            .Repeat.Once();

        var client = new Client(soure);
        client.GetMeMyThing(key);
        client.GetMeMyThing(key);

        source.AssertWasCalled(x => x.GetSomethingThatTakesALotOfResources(key),
                               x => x.Repeat.Once());
        source.VerifyAllExpectations();
    }
于 2009-05-20T05:21:01.223 に答える
5

Rhino Mocks 3.5 のドキュメント (以下に引用) からのこのビットに興味があるかもしれません。期待どおりに動作させるには、クラスをスタブするのではなく、モックする必要があるようです。

スタブとモックの違い

...

モックは、期待を設定できるオブジェクトであり、期待されるアクションが実際に発生したことを検証します。スタブは、テスト対象のコードに渡すために使用するオブジェクトです。特定の方法で動作するように期待を設定できますが、それらの期待が検証されることはありません。スタブのプロパティは自動的に通常のプロパティのように動作し、期待値を設定することはできません。

テスト中のコードの動作を検証したい場合は、適切な期待値でモックを使用し、それを検証します。特定の方法で動作する必要があるが、このテストの焦点では​​ない値を渡すだけの場合は、スタブを使用します。

重要: スタブが原因でテストが失敗することはありません。

于 2008-11-13T03:27:34.623 に答える
2

WhenCalled にデリゲートを渡して呼び出しをカウントできます。

...
uint callCount = 0;
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
    .Return(new Something())
    .WhenCalled((y) => { callCount++; });
...
Assert.AreEqual(1, callCount);

また、スタブではなくモックを使用し、モックに対する期待も検証する必要があります。

于 2011-03-04T00:59:41.983 に答える
2

これが私がやったことです(レイ・ヒューストンの推奨による)。よりエレガントなソリューションをいただければ幸いです...

[Test]
public void just_once()
{
    var key = "id_of_something";

    var source = MockRepository.GenerateStub<ISomeDataSource>();

    // set a positive expectation
    source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
        .Return(new Something())
        .Repeat.Once();

    var client = new Client(soure);

    client.GetMeMyThing(key);

    // set a negative expectation
    source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
        .Return(new Something())
        .Repeat.Never();

    client.GetMeMyThing(key);
}
于 2008-11-13T02:51:57.457 に答える
-1

"Exactly" と呼ばれる機能があれば、そうでなければ無限ループに陥る可能性のあるコードのテストを作成するのに便利です。メソッドの 2 回目の呼び出しで例外が発生するようなテストを作成したいと考えています。

Python の一部のライブラリでは期待値を順序付けできるため、最初のライブラリでは false が返され、2 番目のライブラリでは例外が発生します。

Rhinoはそれをしません。.Once を使用した部分モックは最初の呼び出しをインターセプトし、残りは元のメソッドに渡されます。それはひどいですが、それは本当です。

ハンドモックを作成する必要があります。「テスト可能な」クラスを派生させ、最初の呼び出し後に発生させる機能を与えます。

于 2009-04-21T15:04:06.387 に答える