覆盖 Autofac 注册 - 使用 DI 进行集成测试

Override Autofac registration - Integration tests with DI

我为我的应用程序编写集成测试,并为此使用我的容器。我希望能够像在真实 运行 中那样注册所有组件,然后覆盖一些组件并将它们切换为使用存根实现。

我不想分离 DI 并拥有一个用于测试的容器,只是因为我想测试真实的东西。

这样做也很丑陋:

public class MyRegistrations
{
     public static RegisterAll(bool isInTest= false)
     {
           if (isTest) 
           {
             // Register test fakes
            }
            else
                  // Register real components
      }
}

所以我想到了在我的测试环境中覆盖注册。应该怎么做?

还有其他更好的方法来实现我的目标吗?

谢谢

好吧,例如,您可以在组合根目录中创建一个静态操作方法来更改当前配置并在测试期间调用它。例如:

public class CompositionRoot
{
    public static Action<IContainer> OverrideContainer = c => { };

    internal static IContainer CreateContainer()
    {
        ContainerBuilder builder = new ContainerBuilder();

        /// etc. etc.

        var container = builder.Build();

        OverrideContainer(container);

        return container;
    }
}

之后你可以创建一个模拟你的服务器,例如,像这样:

[TestFixture]
public class ConfigurationControllerFixture : BaseServer
{
    [Test]
    public async Task verify_should_get_data()
    {
        var response = await GetAsync(Uri);
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
    }

    protected override string Uri
    {
        get { return "api/configuration"; }
    }
}

public abstract class BaseServer
{
    protected TestServer Server;
    protected abstract string Uri { get; }

    protected virtual void OverrideConfiguration()
    {
        CompositionRoot.OverrideContainer = c =>
        {
            // new autofac configuration
            cb.Update(c);
        };

        AppStartup.OverrideConfiguration = c =>
        {
            // same as explained, but for HttpConfiguration
        };
    }
}

[SetUp]
public void Setup()
{
    OverrideConfiguration();

    Server = Microsoft.Owin.Testing.TestServer.Create(app =>
    {
       var startup = new AppStartup();
            startup.Configuration(app);
    });

    PostSetup(Server);
}

希望对您有所帮助:)

Autofac will use the last registered component as the default provider of that service

From the AutoFac documation.

在您的 arrange/setup/testInit 阶段注册模拟,然后解析 SUT:

[SetUp]
public void TestInit()
{
    Mock<IFoo> mock = new Mock<IFoo>();
    builder.RegisterInstance(mock.object).As<IFoo>();
    ...
    ...
    _target = builder.Resolve<The component>();
}

注:

单例、静态成员和单例生活方式(注册)可能会造成一些麻烦....

如果您想将 API 的集成测试写入数据库,您可以使用 XUnit。 XUnit 使用 TestHost 和 WebApplicationFactory 创建被测系统。使用 XUnit,通过将测试服务添加到服务集合来模拟测试服务非常容易。

我创建了一个使用 XUnit 的开源项目来测试我的 API 使用 mySQL 数据库的工作。例如,请访问此处 https://gitlab.com/quorion-group/quorion-backend-crm