3

I'm facing a strange problem related to AutoFixture and AutoMoqCustomization and how it deals with automocking of concrete classes. I suspect that I'm not using it very well but would like to know what's the problem. First of all her's some context. Let's say I have a class that I want to test :

public class IdentityApplicationService
{
    public IdentityApplicationService(
        TenantProvisioningService tenantProvisioningService)
    {
        // guard clause etc.
        _tenantProvisioningService = tenantProvisioningService;
    }
}

and its dependency class TenantProvisioningService (TenantProvisioningService's dependencies are not relevant here because they will be auto mocked and I don't care about in my test):

public class TenantProvisioningService
{
    readonly IRoleRepository _roleRepository;
    readonly ITenantRepository _tenantRepository;
    readonly IUserRepository _userRepository;

    public TenantProvisioningService(
        ITenantRepository tenantRepository,
        IUserRepository userRepository,
        IRoleRepository roleRepository)
    {
        this._roleRepository = roleRepository;
        this._tenantRepository = tenantRepository;
        this._userRepository = userRepository;
    }
}

and here's my simple test :

[Fact]
public void ShouldReturnTenantWhenCallingProvisionTenant()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    var mockTenantProvisioningService =
        fixture.Freeze<Mock<TenantProvisioningService>>();
    var sut = fixture.Create<IdentityApplicationService>();
    var command = new ProvisionTenantCommand(
        "bla",
        "bla SaaS platform",
        "superadmin",
        "superadmin",
        "admin@bla.bla",
        null,
        null,
        null,
        null,
        null,
        null,
        null);
    var tenant = sut.ProvisionTenant(command);

    // some asserts
}

This doesn't work because when I call fixture.Create<IdentityApplicationService>() then in it's constructor a concrete TenantProvisioningService is injected instead of a proxied one that you can find in mockTenantProvisioningService.Object.

If I rewrite the test like this (note the fixture inject line) everything works as expected (by me at least :))

[Fact]
public void ShouldReturnTenantWhenCallingProvisionTenant()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    var mockTenantProvisioningService =
        fixture.Freeze<Mock<TenantProvisioningService>>();
    fixture.Inject(mockTenantProvisioningService.Object);
    var sut = fixture.Create<IdentityApplicationService>();
    var command = new ProvisionTenantCommand(
        "bla",
        "bla SaaS platform",
        "superadmin",
        "superadmin",
        "admin@bla.bla",
        null,
        null,
        null,
        null,
        null,
        null,
        null);
    var tenant = sut.ProvisionTenant(command);

    // some asserts
}

So my question is : Am I doing it wrong or is it the way it should be? If not please give me the explanation why AutoFixture is behaving like this.

Enrico Campidoglio
  • 56,676
  • 12
  • 126
  • 154
Tomasz Jaskuλa
  • 15,723
  • 5
  • 46
  • 73
  • 1
    *AutoMoq* ignores concrete classes, which is why you are seeing this behaviour: http://blog.ploeh.dk/2010/08/25/ChangingthebehaviorofAutoFixtureauto-mockingwithMoq IOW, this is expected. – Mark Seemann Nov 15 '13 at 15:14
  • While I understand this is expected is it nor defeating the principle of least surprise ? – Tomasz Jaskuλa Nov 15 '13 at 16:02
  • 1
    I don't know - surprise depends upon what you expect... In this case, I think it would also surprise you if *all* instances suddenly turned out to be Mocks of their types... In fact, I'm not sure that I can grasp the complete implications of such a change in behaviour... which was also a motivating factor in designing it as it is now. – Mark Seemann Nov 15 '13 at 16:10

1 Answers1

6

As Mark Seemann points out, this is the expected behaviour.

Below is the code from the original post updated to work with the current version of AutoFixture:

Func<ISpecimenBuilder, bool> concreteFilter = 
    sb => !(sb is MethodInvoker);

var relays = new FilteringRelays(concreteFilter);

var fixture = new Fixture(relays).Customize(
    new AutoMoqCustomization(
        new MockRelay(
            new TrueRequestSpecification())));

The FilteringRelays class remains the same.

Community
  • 1
  • 1
Nikos Baxevanis
  • 10,868
  • 2
  • 46
  • 80