AutoFixture:模拟方法不会返回冻结的实例 [英] AutoFixture: mock methods don't return a frozen instance
问题描述
我正在尝试编写此简单测试:
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屋!