1

I am trying to get AutoFixture to automatically resolve method calls in mocks. According to the accepted answer for this question, Mocking a dependency with AutoFixture, this should work:


[Fact]
public void Test()
{
    var fixture = new Fixture()
        .Customize(new AutoMoqCustomization { ConfigureMembers = true });

    var service = fixture.Freeze<Mock<IService>>();

    service.Setup(x => x.Fail()).Throws(new Exception("Failed"));

    var sut = fixture.Create<SystemUnderTest>();

    Assert.Throws<Exception>(() => sut.Test());
}

public interface IServiceProvider
{
    T Resolve<T>();
}

public interface IService
{
    void Fail();
}

class SystemUnderTest
{
    private readonly IServiceProvider provider;

    public SystemUnderTest(IServiceProvider provider)
    {
        this.provider = provider;
    }

    public void Test()
    {
        var service = provider.Resolve<IService>();

        service.Fail();
    }
}

But this does not seem to work - the IService mock has not been frozen. I get a different instance then the one I setup.

Is there anything I can do? I feel that the linked question/answer was ambiguous - the author of AutoFixture links to a github issue that says that because Moq does not have extensibility point for that, it is not possible. But the accepted answer gives me an example that is very similar to my case here, but doesn't work. Not only that, the accepted answer mentions a mechanism in AutoFixture itself that solves the problem:

{ ConfigureMembers = true }

EDIT:

I also don't want to setup the IServiceProvider mock, because this is pretty close to the real situation - IServiceProvider is a service provider and is used to resolve dependencies inside each constructor. In quite a few cases, the service factory resolves to other factories. This turns tedious rather quickly. Instead of doing this:


//AutoMoq attribute inherits AutoData and sends in 
//AutoMoq customized fixture to AutoData constructor
[Theory, AutoMoq] 
public void Test([Frozen]Mock<IService> service, SystemUnderTest sut)
{
    service.Setup(x => x.Fail()).Throws(new Exception("Failed"));
    Assert.Throws<Exception>(() => sut.Test());
}

Just as if I was using regular dependency injection. Instead, I am have to do the following:

[Theory, AutoData]
public void Test(IFixture fixture)
{
    var serviceProvider = fixture.Freeze<Mock<IServiceProvider>>();
    var service = fixture.Freeze<Mock<IService>>();

    serviceProvider
        .Setup(x => x.Resolve<IService>())
        .Returns(service.Object);

    service.Setup(x => x.Fail()).Throws(new Exception("Failed"));
    Assert.Throws<Exception>(() => sut.Test());
}

If the Resolve returns a factory, it gets even more tedious.

Eric Ruder
  • 463
  • 5
  • 15

0 Answers0