如何在.NET Core中对Startup.cs进行单元测试 [英] How to Unit Test Startup.cs in .NET Core

查看:448
本文介绍了如何在.NET Core中对Startup.cs进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

人们如何着手对.NET Core 2应用程序中的Startup.cs类进行单元测试?所有功能似乎都是由静态扩展方法提供的,这些方法是不可模拟的?

How do people go about Unit Testing their Startup.cs classes in a .NET Core 2 application? All of the functionality seems to be provided by Static extensions methods which aren't mockable?

如果以这种ConfigureServices方法为例:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<BlogContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddMvc();
}

如何编写测试以确保AddDbContext(...)&会调用AddMvc(),通过扩展方法实现所有这些功能的选择似乎使其无法测试了吗?

How can I write tests to ensure that AddDbContext(...) & AddMvc() are called, The choice of implementing all of this functionality via Extensions methods seems to have made it untestable?

推荐答案

是的,如果您想检查在services上调用了扩展方法AddDbContext的事实,您会遇到麻烦. 好消息是您实际上不应检查这个事实.

Well yes, if you want to check the fact that extension method AddDbContext was called on services you are in trouble. The good thing is that you shouldn't actually check exactly this fact.

Startup类是应用程序组合根.而且,在测试组合根时,您需要检查它是否实际注册了实例化根对象所需的所有依赖项(对于ASP.NET Core应用程序为控制器).

Startup class is an application composition root. And when testing a composition root you want to check that it actually registers all dependencies required for instantiation of the root objects (controllers in the case of ASP.NET Core application).

假设您有以下控制器:

public class TestController : Controller
{
    public TestController(ISomeDependency dependency)
    {
    }
}

您可以尝试检查Startup是否已注册ISomeDependency的类型.但是ISomeDependency的实现也可能需要其他一些依赖项,您应该检查这些依赖项. 最终,您最终得到一个测试,该测试包含大量针对不同依赖项的检查,但实际上并不能保证对象解析不会抛出缺少的依赖项异常.这样的测试没有太大的价值.

You could try checking whether Startup has registered the type for ISomeDependency. But implementation of ISomeDependency could also require some other dependencies that you should check. Eventually you end up with a test that has tons of checks for different dependencies but it does not actually guarantee that object resolution will not throw missing dependency exception. There is not too much value in such a test.

在测试合成根时,一种对我有效的方法是使用真实的依赖项注入容器.然后,我在其上调用合成根,并断言不会抛出根对象的分辨率.

An approach that works well for me when testing a composition root is to use real dependency injection container. Then I call a composition root on it and assert that resolution of the root object does not throw.

不能将其视为纯单元测试,因为我们使用了其他非存根类.但是,与其他集成测试不同,此类测试是快速且稳定的.最重要的是,它们带来了有效检查的价值,以进行正确的依赖项注册.如果这样的测试通过,则可以确保该对象也将在产品中正确实例化.

It could not be considered as pure Unit Test because we use other non-stubbed class. But such tests, unlike other integration tests, are fast and stable. And most important they bring the value of valid check for correct dependencies registration. If such test passes you could be sure that object will also be correctly instantiated in the product.

以下是此类测试的示例:

Here is a sample of such test:

[TestMethod]
public void ConfigureServices_RegistersDependenciesCorrectly()
{
    //  Arrange

    //  Setting up the stuff required for Configuration.GetConnectionString("DefaultConnection")
    Mock<IConfigurationSection> configurationSectionStub = new Mock<IConfigurationSection>();
    configurationSectionStub.Setup(x => x["DefaultConnection"]).Returns("TestConnectionString");
    Mock<Microsoft.Extensions.Configuration.IConfiguration> configurationStub = new Mock<Microsoft.Extensions.Configuration.IConfiguration>();
    configurationStub.Setup(x => x.GetSection("ConnectionStrings")).Returns(configurationSectionStub.Object);

    IServiceCollection services = new ServiceCollection();
    var target = new Startup(configurationStub.Object);

    //  Act

    target.ConfigureServices(services);
    //  Mimic internal asp.net core logic.
    services.AddTransient<TestController>();

    //  Assert

    var serviceProvider = services.BuildServiceProvider();

    var controller = serviceProvider.GetService<TestController>();
    Assert.IsNotNull(controller);
}

这篇关于如何在.NET Core中对Startup.cs进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆