【问题标题】:How to inject dependencies into IClassFixture in XUnit?如何将依赖项注入 XUnit 中的 IClassFixture?
【发布时间】:2021-08-05 22:08:23
【问题描述】:

我正在使用 XUnit,需要在运行测试套件之前执行一些操作。所以,我尝试使用 XUnit 的 IClassFixture 功能。但我找不到将依赖项注入 Fixture 类的方法。我的代码结构如下:

public class MyFixture
{
    IDependency _dep;

    public MyFixture(IDependency dep)
    {
        _dep = dep;
    }
    
    void DoSomeJob()
    {
       //// some code there
       dep.DoSome();
    } 
}  

这是我的测试类代码:

public class MyTest : IClassFixture<MyFixture>
{
    [Fact]
    public void test_my_code()
    {
        ////simply just test the code
    }
}

但是当我运行测试时出现异常

Xunit.Sdk.TestClassException 类夹具类型“MyFixture”有一个或多个未解析的构造函数

【问题讨论】:

  • Xunit 不会那样做依赖注入。为什么会呢?我想不出这样做的正当理由。你能否举一个更好(不那么做作)的例子?
  • IClassFixture 的目标是构建这些依赖项并通过将IClassFixture 的实例“注入”到测试类来共享它们。
  • 试试 xunit 框架中内置的 xunit di 支持:nuget.org/packages/Xunit.Di,这样您就可以像对任何其他应用程序一样注入服务依赖项。

标签: c# .net-core xunit


【解决方案1】:

您的 Fixture 类依赖于未配置的 IDependency dep。您可以使用 Fixture 类来设置服务提供者;但是,这不是最好的解决方案,因为您最终必须使用服务定位器模式,例如

serviceProvider.GetRequiredService<T>()

建议使用xunit.di,它是xunit框架内置的一个扩展,支持构造函数依赖注入,它允许我们在测试类及其依赖之间实现控制反转(IoC)。

Install-Package Xunit.Di

使用 xunit.di:

  • 安装 xunit.di nuget 包
  • 创建一个 Setup.cs 类来配置依赖项(可选)并继承 Xunit.Di.Setup.cs
  • 在 Setup.cs 类中配置依赖项。

xunit.di GET-STARTED 找到完整的说明和演示

您的测试项目具有以下内容:

  • 具有公共 IServiceProvider 的设置类,用于配置所有依赖项
  • 使用构造函数注入依赖项的测试类

您的 Setup.cs 类如下所示:

    private IServiceProvider _services;
    private bool _built = false;
    private readonly IHostBuilder _defaultBuilder;

    public Setup()
    {
        _defaultBuilder = Host.CreateDefaultBuilder();
    }

    public IServiceProvider Services => _services ?? Build();

    private IServiceProvider Build()
    {
        if (_built)
            throw new InvalidOperationException("Build can only be called once.");
        _built = true;

        _defaultBuilder.ConfigureServices((context, services) =>
        {
            services.AddSingleton<TextReaderService>();
            services.AddSingleton<IDependency, DependencyImpl>();
            // where DependencyImpl implements IDependency
            // ... add other services needed
        });

        _services = _defaultBuilder.Build().Services;
        return _services;
    }

那么你的测试类如下所示:

public class MyTest
{
    private readonly IDependency _dependency;

    public MyTest(IDependency dependency)
    {
        _dependency = dependency;
    }

    [Fact]
    public void test_my_code()
    {
        var result = _dependency.DoStuff();
        Assert.NotNull(result);
        ////simply just test the code
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 2011-01-10
    • 2019-09-03
    • 2020-08-14
    • 1970-01-01
    相关资源
    最近更新 更多