首页 > 解决方案 > C# xUnit 中的递归类固定装置

问题描述

我想做这样的事情来提供从测试类到使用组合的其他测试类的方法。

public class SomeTestClass : IClassFixture<SomeService>
{
    private readonly SomeService SomeService;

    public SomeTestClass(SomeService someService)
    {
        SomeService = someService;
    }

    [Fact]
    private void Test()
    {
        //....
    }

    public SomeData CreateSomeData()
    {
       // populate fields with something based on internal/service state
        return new SomeData(); 
    }

    public void DoSomeAction(....)
    {
        // does action which modifies internal/service state
    }

}

public class SomeConsumingClass : IClassFixture<SomeTestClass>
{
    private readonly SomeTestClass SomeTestClass;

    public SomeConsumingClass(SomeTestClass someTestClass)
    {
        SomeTestClass = someTestClass;
    }

    [Fact]
    private void Test()
    {
        var data = SomeTestClass.CreateSomeData();
        // ....
        SomeTestClass.DoSomeAction(...)
    }
}

SomeTestClass 中的测试通过但 SomeConsumingClass 中的测试失败并显示一条消息

类夹具类型“Requirements.SomeTestClass”有一个或多个未解析的构造函数参数:SomeService someService)(以下构造函数参数没有匹配的夹具数据:SomeTestClass someTestClass

似乎没有直接支持这样的功能,因为它似乎正在寻找无参数的构造函数。我打算为每个测试类使用这种模式,因此我正在寻找一些好的方法来做类似的事情,而不需要太多的样板代码。关于如何在没有继承的情况下提供其他测试类的方法的任何建议?

编辑:添加了一些其他示例,我如何想象自己使用它

标签: c#xunit

解决方案


来自关于 Class Fixtures 的 xUnit 文档(强调添加):

请注意,您无法控制夹具对象的创建顺序,并且夹具不能依赖于其他夹具。如果您需要控制创建顺序和/或夹具之间的依赖关系,您应该创建一个封装其他两个夹具的类,以便它可以自己创建对象。

一种解决方案是将CreateSomeData方法移至SomeService,然后进行更改SomeConsumingClass以使其也实现IClassFixture<SomeService>

IClassFixture但是,值得从有关何时合适的文档中指出这一行:

何时使用:当你想创建一个单独的测试上下文并在类中的所有测试之间共享它,并在类中的所有测试完成后清理它。

从您提供的描述来看,我似乎不清楚IClassFixture这里是否有必要,因为您真正想要的只是能够CreateSomeData从不同的测试类中调用。一个非常简单的替代方案是只移动GetSomeData到一个可以从任何需要它的测试夹具直接调用的实用程序类。


推荐阅读