web-dev-qa-db-ja.com

メソッドが1回だけ呼び出されることを主張する

メソッドが1回だけ呼び出されることを主張したいと思います。 RhinoMocks3.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()が呼び出された場合、このテストを失敗させたいと思います。

28

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

[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();
}
32

私はこの問題を回避するために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();
    }
15
Jon Cahill

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

スタブとモックの違い

.。

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

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

重要:スタブによってテストが失敗することはありません。

5
tvanfosson

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

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

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

2
Ergwun

これが私が今やったことです( Ray Houston が推奨するように)。もっとエレガントな解決策をいただければ幸いです...

[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);
}
2

メソッドが1回だけ呼び出されるようにする場合は、厳密なモックを作成できます。

var mock = MockRepository.GenerateStrictMock<IMustOnlyBeCalledOnce>();
mock.Expect(a => a.Process()).Repeat.Once();
var helloWorld= new HelloWorld(mock);

helloworld.Process()

mock.VerifyAllExpectations();
0
Balpreet Patil