Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does AutoFixture.AutoMoq make recursive mocks by default?

Moq does not make recursive mocks by default. That is, for members without expectations on a mock, Moq returns default values. For example, given:

public interface IFoo
{
    Bar Bar();
}

and

public class Bar
{
}

then:

[TestMethod]
public void RecursiveMocksAreDisabledByDefaultInMoq()
{
    var foo = new Mock<IFoo>().Object;
    Assert.IsNull(foo.Bar());
}

However, in AutoFixture.AutoMoq, recursive mocks are enabled by default, as in:

[TestMethod]
public void RecursiveMocksAreEnabledByDefaultInAutoFixture()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    var foo = fixture.Create<IFoo>();
    Assert.IsNotNull(foo.Bar());
}

Why is that? And, how to turn off automatic recursive mocks in AutoFixture.AutoMoq?

Thanks

Moq.3.1.416.3
AutoFixture.AutoMoq.3.16.5
like image 745
beluchin Avatar asked Feb 20 '14 23:02

beluchin


1 Answers

The comments to the question ought to answer the original question of why, but then there's the follow-up comment:

It would be nice, though, to have an easy way to disable [recursive mocks].

It's not that hard to do. If you look at the implementation of AutoMoqCustomization, it's the use of MockPostProcessor that turns on recursive mocks. If you don't want that, you can create your own Customization that doesn't do that:

public class AutoNonRecursiveMoqCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        if (fixture == null)
            throw new ArgumentNullException("fixture");

        fixture.Customizations.Add(
            new MethodInvoker(
                new MockConstructorQuery()));
        fixture.ResidueCollectors.Add(new MockRelay());
    }
}

MockPostprocessor also sets CallBase to true, so by omitting MockPostprocessor you also disable that CallBase setting.

like image 82
Mark Seemann Avatar answered Sep 28 '22 08:09

Mark Seemann