AutoFixture:模拟方法不会返回冻结的实例 [英] AutoFixture: mock methods don't return a frozen instance

查看:69
本文介绍了AutoFixture:模拟方法不会返回冻结的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写此简单测试:

I'm trying to write this simple test:

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的代码是

The Verify check fails.
The code for postProcessor.Process is

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

    postProcessingAction.Do();
}

postProcessingActionReader是通过构造函数初始化的接口字段.

postProcessingActionReader is an interface field initialized through the constructor.

我期望测试通过,但失败了,结果证明从CreatePostProcessingActionFromJobResultXml方法返回的IPostProessingAction实例与从fixture.Freeze<>返回的实例不同.

I'm expecting the test to pass but it fails, it turns out the instance of IPostProessingAction returned from the CreatePostProcessingActionFromJobResultXml method is not the same instance as returned from fixture.Freeze<>.

我的期望是,冻结此Mock对象后,它将在所需的每个位置注入IPostProcessingAction接口的基础模拟,并使所有返回IPostProcessingAction的模拟方法返回相同的对象.

My expectation was that after freezing this Mock object it would inject the underlying mock of the IPostProcessingAction interface in every place its required as well as make all mock methods returning IPostProcessingAction return this same object.

我对模拟方法的返回值的期望不正确吗? 有没有一种方法可以更改此行为,以使模拟方法返回相同的冻结实例?

Is my expectation about the return value of the mock methods incorrect? Is there a way to change this behavior so that mock methods return the same frozen instance?

推荐答案

您需要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);
}


如果您在xUnit.net中将声明性地使用,则扩展可以进一步简化测试:


In case you use AutoFixture declaratively with the xUnit.net extension the test could be simplified even further:

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

这篇关于AutoFixture:模拟方法不会返回冻结的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆