2

AutoFixtureを使用してAbstractクラスの単体テストを作成しています。これは、私がやろうとしていることを表しています。

public abstract class Base
{
    public virtual void DoSomethingCool()
    {
        OnDoingSomethingCool();
    }

    protected abstract void OnDoingSomethingCool();
}

私の単体テストは次のようになります。

[TestMethod]
public void TestMethod1()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());

    var sut = fixture.Create<Base>();

    // How to assert that the OnDoingSomethingCool method was called
    sut.Invoking(x => x.DoSomethingCool())
        .ShouldNotThrow();
}

では、保護された抽象メソッドが実際にメソッドで呼び出されたことをどのように主張しますDoSomethingCoolか?

注入された依存性からのオブジェクトである場合、を使用してモックをセットアップし、メソッドが呼び出されたことを表明できますが、メソッドはテスト対象のサブジェクト内Moqの抽象メソッドであるため、メソッドが呼び出されたことをどのようにアサートしますか?

4

1 に答える 1

6

これについて言えることはたくさんあります:

  1. テストが多すぎるか、他の実装に制御を与えすぎているようです。

    • (制御が多すぎる) 通常、あるメソッドを別のメソッドから強制的に呼び出したい場合は、abstract classそれを作成しませんpublic virtual。これにより、将来の実装でこの動作を変更できるようになります。実際、 を削除するvirtualと、必要なテストを取得できます (以下を参照)。を保持する方法を提供しましたvirtualが、やはり...お勧めしません。あなたの SUT はあなたのモックなので、これはお勧めできません。
    • (テストが多すぎる) テストが脆弱になりすぎないように、実装の詳細ではなく、基本的な動作のみを気にする必要があります。メソッドへの呼び出し以上のものがあると想定していOnDoingSomethingCoolます。それ以外の場合は、それをメイン メソッドにする必要があります。主な動作がこの呼び出しである場合 (この呼び出し以外にもある場合)、NotRecommended以下のメソッドでそれについて説明します。
  2. 抽象クラスを直接テストしないでください。Roy Osherove がThe Art of Unit TestingAbstract Test Class Patternと呼んでいるものを使用する必要があります。これにより、すべての実装で動作がテストされます。その後、依存関係を渡すことができます。その例またはAbstract Test Class Patternからの単純化された例が必要な場合は、お知らせください

/

using Moq.Protected;

...

public void NotRecommended_ProbablyTestingTooMuch_BrittleTestBelow
{
    //If you MUST keep DoSomethingCool virtual
    //var baseMock = new Mock<Base>{CallBase = true};
    var baseMock = new Mock<Base>();
    baseMock.Protected().Setup("OnDoingSomethingCool");

    baseMock.Object.DoSomethingCool();

    baseMock.Protected().Verify("OnDoingSomethingCool", Times.AtLeastOnce());
}
于 2013-03-20T18:54:21.137 に答える