Question

I have a Web API project which has following class. This class is basically registering all the ApiController instances and setting up DependencyResolver.

public class DependencyResolverConfig
{
    public static void Register(HttpConfiguration configuration, ContainerBuilder containerBuilder)
    {
        containerBuilder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        var container = containerBuilder.Build();
        var resolver = new AutofacWebApiDependencyResolver(container);
        configuration.DependencyResolver = resolver;
    }
}

To test that this class is actually setting up all API controllers, I have following test

[Test]
public void RegistersApiControllers()
{
    var config = new HttpConfiguration();
    var containerBuilder = Substitute.For<ContainerBuilder>();
    containerBuilder.RegisterApiControllers(Arg.Any<Assembly>());

    DependencyResolverConfig.Register(config, containerBuilder);
    containerBuilder.Received(2).RegisterApiControllers();
}

When I run this test, I get following exception from NSubstitute

NSubstitute.Exceptions.ReceivedCallsException : Expected to receive exactly 2 calls matching:
    RegisterCallback(Action<IComponentRegistry>)
Actually received no matching calls.
Received 2 non-matching calls (non-matching arguments indicated with '*' characters):
    RegisterCallback(*Action<IComponentRegistry>*)
    RegisterCallback(*Action<IComponentRegistry>*)

This is confusing output. I fail to understand why NSubstitute is not happy when the actual call and expected call are exactly same. Any clues?

Was it helpful?

Solution

As already was said, RegisterApiControllers is an extension method, only virtual members can be intercepted by NSubstitute.

But it's not that bad, it sticks you to have more clear and loosely coupled design through tests. With tools like Fakes or JustMock you can mock everything, and they don't force you to make the system loosely coupled.

I think your test is useless, the thing that you registered the controllers does not mean you can resolve them. I would suggest to test that you can resolve them. Something like this:

[Test]
public void ResolvesServiceController()
{
    // Arrange
    var configuration = new HttpConfiguration();
    var containerBuilder = new ContainerBuilder();
    DependencyResolverConfig.Register(configuration, containerBuilder);

    // Act
    var controller = configuration.DependencyResolver.GetService(typeof (ServiceController));

    // Assert
    Assert.IsNotNull(controller);
} 

Then you can make further refactorings, ie create an Autofac module where you register your controllers and their dependencies, then test exact this module.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top