繁体   English   中英

单元测试中的依赖注入,xUnit

[英]Dependency injection in unit testing, xUnit

这可能是一个愚蠢的问题,但我有这样的日子。

我有一个名为 JwtManager 的JwtManager和一个名为IJwtManager的接口,我正在尝试将接口注入到单元测试The following constructor parameters did not have matching fixture data: IJwtManager jwtManager中,以便我可以对其进行测试,但它不起作用,编译器给了我这个消息: The following constructor parameters did not have matching fixture data: IJwtManager jwtManager

我认为问题是编译器不知道接口应该映射到什么 class,但是我怎样才能在测试 class 中编写等效的services.AddScoped<>()

测试 class 的代码示例:

public class JwtManagerTests
{
    private readonly IJwtManager jwtManager;
    public JwtManagerTests(IJwtManager jwtManager)
    {
        this.jwtManager = jwtManager;
    }

    [Fact]
    public void Test_Something()
    {
        // Test here
    }
}

将 DI 容器与单元测试项目一起使用是可能的,但确实有点矫枉过正。 它迫使您在测试之间共享依赖关系,这使得调整依赖关系的行为以适应特定测试变得更加困难,因为您最终会破坏其他测试。

相反,我们应该努力在我们的测试方法中定义被测系统的依赖关系。 您提到您的 JwtManager class 依赖于 IConfiguration。 没问题。

[Fact]
public void JwtManagerShouldCreateJwtWhenDetailsAreValid()
{
    // Arrange
    var configuration = new ConfigurationBuilder().AddInMemoryCollection(
    new Dictionary<string, string>
    {
        { "section:key1", "value1" },
        { "section:key2", "value2"}
    }).Build();

    var jwtManager = new JwtManager(configuration);

    // Act
    var result = jwtManager.CreateJwt("some input");

    // Assert
    result.Should().BeAValidJwt();
}

关于这一点的一件好事是您不必向您的配置 object 添加任何配置,除非正是测试需要。 如果 JwtManager 的不同测试需要不同的配置设置来测试不同的场景,那么现在很容易做到,因为配置不是来自单个 IoC 容器。

不过,我会告诫不要直接依赖您的课程中的 IConfiguration 。 通常最好改用强类型 class。 它使依赖关系更加清晰(您不必打开 JwtManager 来查看它将从 IConfiguration 使用的设置)并且在测试中语法更清晰。 例如:

public class JwtManagerSettings
{
    public string SomeSetting { get; set; }

    public int SomeOtherSetting { get; set; }
}

public class JwtManager
{
    readonly JwtManagerSettings _settings;

    public JwtManager(JwtManagerSettings settings)
    {
        _settings = settings;
    }
}

[Fact]
public void JwtManagerShouldCreateJwtWhenDetailsAreValid()
{
    // Arrange
    var settings = new JwtManagerSettings
    {
        SomeSetting = "abc",
        SomeOtherSettings = 123
    };

    var jwtManager = new JwtManager(settings);

    // Act
    var result = jwtManager.CreateJwt("some input");

    // Assert
    result.Should().BeAValidJwt();
}

在您的实际应用中,Microsoft.Extensions.Configuration 完全能够从 IConfiguration 解析复杂类型,例如 JwtManagerSettings。 无论您在何处配置 IoC 容器(例如 Startup.cs),您都可以执行以下操作:

//assuming your settings are defined in a JSON key called "JwtManager"
var jwtManagerSettings = configuration.Get<JwtManagerSettings>("JwtManager");
services.AddSingleton(jwtManagerSettings);
{
    "JwtManager": {
        "SomeSetting": "abc",
        "SomeOtherSetting": 123
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM