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

时间:2016-04-07 08:32:48

标签: c# unit-testing dependency-injection integration-testing autofac

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

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

这样做看起来也很难看:

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

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

实现目标的其他更好方法是什么?

由于

3 个答案:

答案 0 :(得分:2)

  

Autofac将使用最后注册的组件作为默认提供程序   那项服务

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>();
}

注意:

单身人士,静态成员和SingletonLifestyle(注册)可能会引起一些麻烦......

答案 1 :(得分:1)

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

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);
}

希望有所帮助:)

答案 2 :(得分:0)

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

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