我正在尝试编写这个简单的测试:
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
的模拟方法返回同一个对象。 / p>
我对mock方法的返回值的期望是否不正确? 有没有办法改变这种行为,以便mock方法返回相同的冻结实例?
答案 0 :(得分: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);
}
如果您将自动混合declaratively与xUnit.net extension一起使用,则可以进一步简化测试:
[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()))
{
}
}
答案 1 :(得分:4)
从3.20.0开始,您可以使用AutoConfiguredMoqCustomization
。这将自动配置所有模拟,以便其成员&#39;返回值由AutoFixture生成。
换句话说,它会自动配置您的postProcessingActionReader
以返回冻结的postProcessingAction
。
只需改变一下:
var fixture = new Fixture().Customize(new AutoMoqCustomization());
到此:
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());