AutoFixture: mock methods do not return a frozen instance

I am 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 Error.
The code for postProcessor.Process is

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

postProcessingActionReader is an interface field initialized by the constructor.

I expect the test to pass, but it fails, it turns out that the IPostProessingAction instance returned from the CreatePostProcessingActionFromJobResultXml method is not the same instance as the one returned from fixture.Freeze<> .

My expectation was that after freezing this Mock object, it would introduce the basic layout of the IPostProcessingAction interface in every place it needed, and also make all the mock methods that returned IPostProcessingAction return the same object.

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

+6
source share
2 answers

You need the Freeze component of IPostProcessingActionReader .

The next test will pass:

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

Assuming types are defined as:

 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); } 

If you use AutoFixture declaratively with the xunit.net extension, the test could be further simplified:

 [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 defined as:

 internal class AutoMoqDataAttribute : AutoDataAttribute { internal AutoMoqDataAttribute() : base(new Fixture().Customize(new AutoMoqCustomization())) { } } 
+5
source

Starting with 3.20.0, you can use AutoConfiguredMoqCustomization . This will automatically configure all mocks so that the return values ​​of their members are generated using AutoFixture.

In other words, it will automatically configure your postProcessingActionReader to return a frozen postProcessingAction .

Just change this:

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

:

 var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization()); 
+4
source

All Articles