【问题标题】:NancyFX Functional Testing with Autofac使用 Autofac 进行 NancyFX 功能测试
【发布时间】:2014-11-08 08:56:44
【问题描述】:

我已将 Autofac 实现为我选择的 DI 容器,以代替 Nancy 中的默认设置 TinyIoC。

我的 API 已经正常工作,我可以通过浏览器轻松连接到它,但是我的功能测试失败了。他们失败了,因为我试图使用 Nancy Browser 来设置测试,但它需要 TinyIoC 容器(不存在)。

有没有一种简单的方法来扩展/覆盖浏览器以采用 Autofac 容器而不是 TinyIoC 容器?或者(可能更好),是否有一个“可以”使用不同容器的 Nancy.Testing 浏览器?

SetUp : System.InvalidOperationException : 出现问题时 试图在合成过程中满足其中一个依赖项,使 确保您已在容器中注册了所有新依赖项,并且 检查内部异常以获取更多详细信息。 ----> Nancy.TinyIoc.TinyIoCResolutionException:无法解析类型: Nancy.NancyEngine ----> Nancy.TinyIoc.TinyIoCResolutionException : 无法解析类型:Nancy.Routing.DefaultRequestDispatcher ----> Nancy.TinyIoc.TinyIoCResolutionException:无法解析类型: Nancy.Routing.DefaultRouteResolver ----> Nancy.TinyIoc.TinyIoCResolutionException:无法解析类型: Nancy.Routing.RouteCache ----> Nancy.TinyIoc.TinyIoCResolutionException:无法解析类型: TimeTracker.Web.Api.UserModule ----> Nancy.TinyIoc.TinyIoCResolutionException:无法解析类型: TimeTracker.Services.IUserService

如您所见,TinyIoC 无法解析 IUserService。

Nancy.TinyIoc.TinyIoCResolutionException:无法解析类型: TimeTracker.Services.IUserService

这是因为我没有在 TinyIoC 上注册任何东西...而是在 Autofac 上注册它。

    [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;

【问题讨论】:

  • 似乎缺少 IUserService。您是否尝试过通过 with.Dependency 提供 IUserService?
  • @ChristianHorsdal 不幸的是,这与它无关。事实上,我没有使用 Nancy 想要的默认容器。
  • 你怎么知道的? - 从你在问题中发布的内容来看,我似乎不是那样的。

标签: autofac functional-testing nancy


【解决方案1】:

如果您想在测试时使用 Autofac 引导程序,则需要使用 Browser(INancyBootstrapper bootstrapper, Action&lt;BrowserContext&gt; defaults = null) 构造函数并明确指定引导程序的实例。

这种方法的问题在于,您很难“替换”组件以进行测试,即使用模拟等,这就是 ConfigurableBootstrapper 存在的原因。我也不太确定它将如何影响模块发现。使用ConfigurableBootstrapper,您可以明确说明要与其他服务一起使用哪些模块。

【讨论】:

  • 嗯,有道理。我把它复杂化了。 var bootstrapper = new BootStrapper(); _browser = new Browser(bootstrapper);
  • 好的,所以在测试了这种方法之后,我的 API 总是抛出 404。我还没有深入调试器看看为什么......