6

私はこの簡単なテストを書こうとしています:

var fixture = new Fixture().Customize(new AutoMoqCustomization());

var postProcessingAction = fixture.Freeze<Mock<IPostProcessingAction>>();
var postProcessor = fixture.Freeze<PostProcessor>();

postProcessor.Process("", "");

postProcessingAction.Verify(action => action.Do());

Verifyチェックは失敗します。
postProcessor.Process のコードは次のとおりです。

public void Process(string resultFilePath, string jobId)
{
    IPostProcessingAction postProcessingAction =
        postProcessingActionReader
            .CreatePostProcessingActionFromJobResultXml(resultFilePath);

    postProcessingAction.Do();
}

postProcessingActionReaderコンストラクターによって初期化されるインターフェイス フィールドです。

テストに合格することを期待していますが、失敗しましIPostProessingActionた。メソッドから返された のインスタンスは、 から返されたインスタンスCreatePostProcessingActionFromJobResultXmlと同じではないことがわかりましたfixture.Freeze<>

私の期待は、この Mock オブジェクトを凍結した後IPostProcessingAction、必要なすべての場所にインターフェイスの基になるモックを挿入し、返されるすべてのモック メソッドIPostProcessingActionがこの同じオブジェクトを返すようにすることでした。

モック メソッドの戻り値についての私の期待は間違っていますか? モック メソッドが同じ凍結されたインスタンスを返すように、この動作を変更する方法はありますか?

4

2 に答える 2

5

Freezeコンポーネントが必要IPostProcessingActionReaderです。

次のテストに合格します。

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

    var postProcessingActionMock = new Mock<IPostProcessingAction>();

    var postProcessingActionReaderMock = fixture
        .Freeze<Mock<IPostProcessingActionReader>>();

    postProcessingActionReaderMock
        .Setup(x => x.CreatePostProcessingActionFromJobResultXml(
            It.IsAny<string>()))
        .Returns(postProcessingActionMock.Object);

    var postProcessor = fixture.CreateAnonymous<PostProcessor>();
    postProcessor.Process("", "");

    postProcessingActionMock.Verify(action => action.Do());
}

タイプが次のように定義されていると仮定します。

public interface IPostProcessingAction
{
    void Do();
}

public class PostProcessor
{
    private readonly IPostProcessingActionReader actionReader;

    public PostProcessor(IPostProcessingActionReader actionReader)
    {
        if (actionReader == null)
            throw new ArgumentNullException("actionReader");

        this.actionReader = actionReader;
    }

    public void Process(string resultFilePath, string jobId)
    {
        IPostProcessingAction postProcessingAction = this.actionReader
            .CreatePostProcessingActionFromJobResultXml(resultFilePath);

        postProcessingAction.Do();
    }
}

public interface IPostProcessingActionReader
{
    IPostProcessingAction CreatePostProcessingActionFromJobResultXml(
        string resultFilePath);
}

AutoFixture を xUnit.net拡張機能で宣言的に使用する場合、テストはさらに簡素化できます。

[Theory, AutoMoqData]
public void Test(
    [Frozen]Mock<IPostProcessingActionReader> readerMock,
    Mock<IPostProcessingAction> postProcessingActionMock,
    PostProcessor postProcessor)
{
    readerMock
        .Setup(x => x.CreatePostProcessingActionFromJobResultXml(
            It.IsAny<string>()))
        .Returns(postProcessingActionMock.Object);

    postProcessor.Process("", "");

    postProcessingActionMock.Verify(action => action.Do());
}

は次のAutoMoqDataAttributeように定義されます。

internal class AutoMoqDataAttribute : AutoDataAttribute
{
    internal AutoMoqDataAttribute()
        : base(new Fixture().Customize(new AutoMoqCustomization()))
    {
    }
}
于 2013-02-05T14:26:54.803 に答える