Functional Testing of NancyFX with Autofac

I used Autofac as my DI container instead of TinyIoC which Nancy uses by default.

The API is working for me and I can easily connect to it through the browser, however my functional tests are not working. They fail because I'm trying to use the Nancy Browser to set up the tests, but it requires a TinyIoC Container (which isn't).

Is there an easy way to extend / override the browser to take the Autofac container instead of TinyIoC? Alternatively (and probably better), there is a Nancy.Testing Browser that "can" use a different container?

SetUp: System.InvalidOperationException: Something went wrong when trying to satisfy one of the dependencies during composition, make sure you register all new dependencies in the container and inspect innerexception for more details. ----> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.NancyEngine ----> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.Routing.DefaultRequestDispatcher ----> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.Routing.DefaultRouteResolver ----> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.Routing.RouteCache ----> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: TimeTracker.Web.Api UserModule ----> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: TimeTracker.Services.IUserService

As you can see, TinyIoC cannot resolve IUserService.

Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: TimeTracker.Services.IUserService

This is because I am not registering BELOW with TinyIoC ... I am registering it with Autofac instead.

    [TestFixtureSetUp]
    public void Setup()
    {
        _browser = new Browser(with =>
            {
                with.Module<UserModule>();

                // forcing me to use TinyIoCContainer
                with.ApplicationStartup((x, pipelines) =>
                    {
                        var container = BootStrapper.ConfigureContainer(new ContainerBuilder().Build());

                        var userValidator = container.Resolve<IUserValidator>();
                        var basicAuthConfig = new BasicAuthenticationConfiguration(userValidator, "TimeTra.ca");
                        pipelines.EnableBasicAuthentication(basicAuthConfig);

                        pipelines.OnError.AddItemToEndOfPipeline(
                            (context, exception) => CustomErrorResponse.FromException(exception));

                        // Setup a clean database
                        var migrationRunner = new MigrationRunner(container.Resolve<IDbProvider>());
                        migrationRunner.DropDatabase();
                        migrationRunner.CreateDatabase();

                        BootStrapper.RunMigrations(container);
                        SeedData.SetupFixtureDataInDatabase(container.Resolve<IServiceLocator>());
                    });
            });
    }

    private Browser _browser;

      

+3


source to share


1 answer


If you want to use the Autofac loader when testing, you need to use the constructor Browser(INancyBootstrapper bootstrapper, Action<BrowserContext> defaults = null)

and explicitly specify an instance of your loader.



The problem with this approach is that it will be difficult for you to "replace" components for testing; use mocks etc, so there is ConfigurableBootstrapper

. I'm also not entirely sure how this will affect module detection. With, ConfigurableBootstrapper

you explicitly indicate which modules you want to use along with other services.

+2


source







All Articles