c# - 如何在 ASP.NET Core 集成测试中覆盖来自其他容器的 DI 注册

标签 c# integration-testing autofac asp.net-core-webapi

我在asp.net core startup.cs文件中有如下注册:

    public void ConfigureContainer(ContainerBuilder builder)
    {
       builder.RegisterType<UserService>().As<IUserService>();
    }

这是配置Autofac容器。我还有另一个集成测试项目,其中有一个 CustomWebApplicationFactory 类,我正在尝试替换 IUserService 接口(interface)的实现。

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureTestServices(services =>
        {
            services.AddSingleton<IUserService, TestUsersService>();
        });
    }

我在调试测试项目的时候好像不行,IUserService的实现还是UserService。

我尝试使用 ASP.NET Core 内置的 IServiceCollection 在 Startup.ConfigureServices 方法中直接注册 UserService,它在调试时有效:

services.AddSingleton<IUserService, UserService>();

那么,当我使用 Autofac 作为 IoC 容器时,如何解决这个问题,集成测试项目会像我预期的那样正常运行?

最佳答案

您可能会遇到操作顺序问题。一般来说,最后获胜。这适用于 Autofac 和基本的 Microsoft DI 容器。

假设you've read through the docs on Autofac ASP.NET Core integration您会看到,当 ConfigureContainer 到位时,操作顺序大致为:

  • WebHost 特定的配置服务
  • 启动类ConfigureServices
  • 启动类ConfigureContainer

当添加 ConfigureTestServices 时,它看起来像(虽然我还没有逐步完成)它在 WebHost 和 Startup 类 ConfigureServices 之后运行...但它仍然在 ConfigureContainer 之前运行。

这很容易测试 - 创建一个具有三种不同实现的服务接口(interface)。在每个级别注册不同的实现。解析 Controller 中的接口(interface)。你得到了哪一个?那是最后一个跑的。现在从应用程序中删除该注册并重试。你得到的下一个是什么?这是倒数第二个。等等。

Autofac 采用预构建的 IServicesCollection 并循环遍历它,将其添加到 native Autofac 容器中。一旦发生这种情况,修改集合就没有关系了。 Autofac 无法控制 ASP.NET Core 中启动机制的执行顺序;它只知道 ASP.NET Core 说,“这是要继续导入的最终服务集合!”如果在正确的阶段没有发生这种情况,您将必须执行以下两项操作之一:

  • 将您需要覆盖的注册从 ConfigureContainer 移到其中一个 ConfigureServices 方法中,使用 Microsoft 注册语言而不是 native Autofac。
  • 以其他方式执行覆盖,例如使用 TestASPNETCORE_ENVIRONMENT 设置并提供 ConfigureTestContainer 方法。 (环境特定注册方法的示例在 the docs 中。)

关于c# - 如何在 ASP.NET Core 集成测试中覆盖来自其他容器的 DI 注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51856614/

相关文章:

c# - Silverlight 中的配置文件

java - Mockito自调用doAnswer重复调用?

android - 无法初始化 MockMaker

dependency-injection - 如何在构建依赖项时查看消息?

c# - OWIN + SignalR + Autofac

c# - 如何使用 Autofac 解决 Nancy 创建的子生命周期范围内类型的每个请求依赖项的实例

c# - DataItem=null on binding,找不到原因?

C# WPF clr-namespace 自动完成但随后给出错误

c# - 如何测试方法是否在特定输入上引发异常

java - Spring CrudRepository deleteAll() 什么都不做