AutoFixture: mock methods don't return a frozen instance

前端 未结 2 414
孤街浪徒
孤街浪徒 2021-01-05 17:23

I\'m trying to write this simple test:

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

var pos         


        
相关标签:
2条回答
  • 2021-01-05 17:43

    You need to Freeze the IPostProcessingActionReader component.

    The following 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 that the 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);
    }
    

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

    The AutoMoqDataAttribute is defined as:

    internal class AutoMoqDataAttribute : AutoDataAttribute
    {
        internal AutoMoqDataAttribute()
            : base(new Fixture().Customize(new AutoMoqCustomization()))
        {
        }
    }
    
    0 讨论(0)
  • 2021-01-05 18:07

    As of 3.20.0, you can use AutoConfiguredMoqCustomization. This will automatically configure all mocks so that their members' return values are generated by AutoFixture.

    In other words, it will auto-configure your postProcessingActionReader to return the frozen postProcessingAction.

    Just change this:

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

    to this:

    var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());
    
    0 讨论(0)
提交回复
热议问题