4

私はしばらくの間moqを使用してモックを作成していて、常に次のようなことをしていることに気づきます。

テストしたい動作が、classUnderTest.DoSomething()がl.Fatal( "My test message")を1回呼び出すことであると想定します。

//arrange
mockLogger.Setup(l => l.Fatal("My test message"));

//act
classUnderTest.DoSomething()

//assert
mockLogger.Verify(l => l.Fatal("My test message"), Times.Once());

検証呼び出しは、Timesパラメーターを除いて、常にセットアップの繰り返しであるように感じます。さまざまなモックフレームワークを使用しても、他の人が何をしているのかを本当に知りたいです。これを行うためのより良い方法はありますか?

4

4 に答える 4

4

Mockオブジェクトの設定を行う必要があるのは、オブジェクトを返すなど、実際にその動作を制御する必要がある場合のみです。

_mockRepo.SetUp(m => m.DoStuff()).Returns(someObject);

または例外をスローします:

_mockRepo.SetUp(m => m.DoStuff()).Throws(new SomeExceptionType());

あなたの例では、ロガーモックオブジェクトをテスト中の他のオブジェクトに渡していると仮定します。この場合、モックオブジェクトを作成するだけで同等のセットアップが行われるため、セットアップ呼び出しを削除しても効果はありません。

編集

public class Dude : IDude
{
    private IAirSupport _support;

    public Dude(IAirSupport support)
    {
        _support = support;
    }

    public void Advance(Place place)
    {
        if(place.IsUnderAttack)
        {
            _support.CoveringFire(place);
            MoveAndFire(place);
        }

    }
}

これをモックするには:

var support = new Mock<IAirSupport>();

var dude = new Dude(support.Object);

var place = new HotSpot { IsUnderFire = true };


dude.Advance(place);

support.Verify(m => m.CoveringFire(place), Times.Once());

必要なのはこれだけです-Verifyはすべての面倒な作業を行い、セットアップを呼び出す理由はありません。

于 2012-11-23T12:47:53.473 に答える
2

繰り返しを感じるというあなたの感情に同意します。ただし、この特定の例では、何も返さないため、電話をかける必要はないと思いますSetup()Setup()私は通常、返されたオブジェクトに基づいて何かをアサートする必要がある場合にのみ呼び出します。

最近、構造マップを介してAutoMockingを使い始めました。これにより、自動生成されたモックにアクセスするために、基本クラスにいくつかのショートカット/ユーティリティメソッドを作成するように促されました。その後、呼び出すためのショートカットを作成することVerify()もできました。キーストロークを1つか2つ節約できるかもしれません... http://evolutionarydeveloper.blogspot.co.uk/2012/10/automock-with-structuremap-and-moq.html

于 2012-11-23T12:18:26.023 に答える
1

このようにテストを再配置してみてください

   //arrange
   var mockLogger = new Mock<ILogger>();
   var classUnderTest = new Foo(mockLogger.Object);

   //act
   classUnderTest.DoSomething();

   //assert
   mockLogger.Verify(l => l.Fatal("My test message"), Times.Once());

このように、ダブルアサーションや重複したテストデータは必要ありません。基本的には、事前に予想される呼び出しを設定して厳密なモックを作成する、構文を使用Setup することをお勧めします。Verify主張されていることが非常に明確であるため、私は個人的に検証構文がより好きです。

于 2012-11-23T15:30:28.040 に答える
0

多くのテストが繰り返し感じられることに同意しますが、あなたが説明するよりもはるかに簡単に物事を行うことができる方法がわかりません。

すべての単体テストは、setup-execute-assert(少なくとも適切なもの)のパターンに従います。これはまさにあなたの例がエレガントに行うことです。どのように設定し、どのように主張するかについて議論することはできますが、それぞれを1行のコードで実行し、それを超える方法を見つけるのは困難です。

于 2012-11-23T13:34:05.397 に答える