45

戻り値のセットアップと、式が呼び出された回数の確認が必要な場合、これを 1 つのステートメントで実行できますか?

私が収集できるものから、MoqSetup(SomeExpression).Verifiable()は と一緒に呼び出されVerify()、基本的にVerify(SomeExpression, Times.AtLeastOnce)? つまり、式が呼び出されたことのみを検証します。

質問をよりよく説明するための例を次に示します。インターフェイスの場合:

interface IFoo
{
    int ReturnSomething();
}

次の 2 つのブロックは同等ですか (最初のブロック以外は、検証可能とマークされたすべてのセットアップを検証します)?

void Test()
{
    var mock = new Mock<IFoo>();
    mock.Setup((m) => m.ReturnSomething()).Returns(1).Verifiable();

    mock.Verify();
}

void Test()
{
    var mock = new Mock<IFoo>();
    mock.Setup((m) => m.ReturnSomething()).Returns(1);

    mock.Verify((m) => m.ReturnSomething(), Times.AtLeastOnce());
}

呼び出しの数を確認したい場合 (たとえば 2 回)、Setup と Verify で式が繰り返される唯一の方法ですか?

void Test()
{
    var mock = new Mock<IFoo>();
    mock.Setup((m) => m.ReturnSomething()).Returns(1);

    mock.Verify((m) => m.ReturnSomething(), Times.Exactly(2));
}

Setup と Verify を呼び出さなければならないのは好きではありません。まあ、これは AAA にとっては良いアイデアなので、言い換えれば、Setup と Verify の表現を繰り返さなければならないのは好きではありません。現時点では、式を変数に格納して各メソッドに渡していますが、あまりクリーンではありません。

PS - このコンテキストは、キャッシュが更新されたかどうか (有効期限など) をテストするためのものです。

4

4 に答える 4

24

私はいつもこの問題を抱えています。私は厳密なモックを使用しており、厳密に指定したい (つまりIt.Is<>()、代わりに使用したIt.IsAny()) だけでなく、厳密に検証したい (つまり、Times を指定する) こともできます。Moq にはVerifiable(Times)オーバーロードがないため、悲しいことに、これに検証可能を使用することはできません。

コールを含む完全な表現は、It.Is<>()一般的に大きいです。したがって、重複を避けるために、私は一般的に次のことに頼っています。

Expression<Action<MockedType>> expression = mockedTypeInstance => mockedTypeInstance.MockedMethod(It.Is<TFirstArgument>(firstArgument => <some complex statement>)/*, ...*/);
_mock.Setup(expression);

/* run the test*/

_mock.Verify(expression, Times.Once);

非常に読みやすいわけではありませんが、厳密なセットアップと厳密な検証の両方を使用する別の方法はないと思います。

于 2016-04-20T13:28:24.860 に答える
16

最初の質問に答えると、はい、2 つのブロックは同等です。.Verifyモックのメソッドが呼び出されなかった場合、 が呼び出されると両方とも失敗します。

私の知る限り、前もって検証を指定することはできません。考えてみれば、それは理にかなっています。

これは、モックの動作を指定しています:

mock.Setup(m => m.ReturnSomething()).Returns(1);

これは、呼び出し元の動作を確認しています:

mock.Verify(m => m.ReturnSomething(), Times.AtLeastOnce());

個人的には、verify を個別に呼び出して、呼び出し元の必要な動作を確認することを好みます。.Verifiable().Verify()はそれほど厳密ではないショートカットです (メソッドが 1 回以上呼び出されたことを確認するだけです)。ただし、コードがメソッドを 1 回だけ呼び出す必要があることがわかっている場合は、それを確認するために最後に検証します。

コードのマージの結果、メソッドが 2 回呼び出された後、テストは少なくとも 1 回呼び出されたので合格しましたが、別の何かが複数回発生したことも意味していました。

于 2013-03-12T12:28:17.863 に答える