C# 如何参数化xunit类fixture?

C# 如何参数化xunit类fixture?,c#,xunit,xunit.net,C#,Xunit,Xunit.net,xUnit提供了(共享)类固定装置的概念,如中所述。到目前为止,我还没有弄明白,是否有一种方法可以参数化这些类装置。例如,如果DatabaseFixture应该使用一些测试数据来丰富,这取决于它所运行的测试,该怎么办?测试类可能希望插入测试数据,但只插入一次,然后针对该数据库(fixture)运行所有测试 换句话说,如果/。。。初始化测试数据库中的数据…来自文档(上文引用)的数据是否也取决于测试?因为并非所有的测试都想要相同的测试数据。事实上,我甚至认为很多时候,测试定义自己的测试数据是一种很好

xUnit提供了(共享)类固定装置的概念,如中所述。到目前为止,我还没有弄明白,是否有一种方法可以参数化这些类装置。例如,如果
DatabaseFixture
应该使用一些测试数据来丰富,这取决于它所运行的测试,该怎么办?测试类可能希望插入测试数据,但只插入一次,然后针对该数据库(fixture)运行所有测试

换句话说,如果
/。。。初始化测试数据库中的数据…
来自文档(上文引用)的数据是否也取决于测试?因为并非所有的测试都想要相同的测试数据。事实上,我甚至认为很多时候,测试定义自己的测试数据是一种很好的做法,以避免在测试数据级别上耦合测试

到目前为止,我所做的工作是提供一个
ConfiguredWith
方法,该方法接收只执行一次的回调。为了做到这一点,我需要延迟测试数据库的初始化,以确保配置选项已设置。比如:

public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
    DatabaseFixture fixture;

    public MyDatabaseTests(DatabaseFixture fixture)
    {
         this.fixture = fixture;
         this.fixture.ConfigureWith(new DatabaseFixtureOptions
         {
             InitTestData = db => db.Insert(...);
         };
    }

    // ... 
}
公共类MyDatabaseTests:IClassFixture
{
数据库夹具;
公共MyDatabaseTests(数据库夹具)
{
这个。夹具=夹具;
this.fixture.ConfigureWith(新的DatabaseFixtureOptions
{
InitTestData=db=>db.Insert(…);
};
}
// ... 
}
在编写针对数据库的测试时,这看起来相当做作,感觉像是一个标准要求

如果xUnit不提供这种开箱即用的服务,也许有人有更好的模式来解决这个问题


似乎也朝着类似的方向发展,但我并不一定固定在一个具有这种结构的解决方案上。

我了解到,通过
IClassFixture
CollectionFixtures
共享实体框架数据库上下文最终会在测试中被另一个测试数据或死锁/竞争所污染由于并行执行xUnit而导致的条件,实体框架抛出异常,因为它已经用给定的Id跟踪了该对象,还有更多类似的麻烦。 就我个人而言,我建议针对您的具体使用原因,将数据库上下文创建/清理放在
构造函数/dispose
选项中,例如:

公共类TestClass:IDisposable
{
数据库上下文数据库上下文;
公共测试类()
{
var options=new DbContextOptionsBuilder()
.UseInMemoryDatabase(数据库名称:Guid.NewGuid().ToString())
.选择;
DatabaseContext=新的DatabaseContext(选项);
//插入要为每个测试方法设定种子的数据:
DatabaseContext.Set().Add(新产品(){Id=1,Name=Guid.NewGuid().ToString()});
DatabaseContext.SaveChanges();
}
[事实]
公共测试()
{
var product=DatabaseContext.Set().FirstOrDefault(x=>x.Id==1).Name;
//产品评估结果为=>0f25a10b-1dfd-4B4B4B-a69d-4ec587fb465b
}
[事实]
公共测试
{
var product=DatabaseContext.Set().FirstOrDefault(x=>x.Id==1).Name;
//产品评估结果=>eb43d382-40a5-45d2-8da9-236d49b68c7a
//它与firstTest不同,因为它是另一个对象
}
公共空间处置()
{
DatabaseContext.Dispose();
}
}

当然你总是可以做一些改进,但是想法就在那里

嗨,德扬,你好吗?为什么在
成员数据
类数据
中使用
理论
不能满足你的需要?在我看来,你寻找的是一组依赖于测试的数据(
成员数据
/
类数据
)RodRamírez不是依赖于测试类(共享上下文:
ClassFixture
/
CollectionFixture
)@RodRamírez当创建测试数据的成本很高(例如:准备物理数据库)时,人们使用类/集合装置,这样这个装置就可以在所有测试中共享。除此之外,我还想看看是否有一种方便的方法来以参数化的方式初始化数据库中的测试数据。如果您希望所有测试在开始之前都有相同的数据集,您应该看看我下面的答案。现在,关于与每个tes相关的数据集ts在给定的测试类中,您可以检查memberData/ClassData方法。@谢谢您的努力。您的建议很简单,因此功能强大,在许多情况下应该是如何针对DB上下文进行冒烟测试的默认方法。但是,这对我来说并不是什么新鲜事,也不是我的答案。在某些情况下,我们有一个更好的解决方案复杂设置(=更高级别的系统测试)这就是为什么我们希望有一个共享的参数化设置的原因。我理解。我也无法在web上的任何地方找到适合你需要的东西。但是,我记得我曾经在xUnit框架上遇到过一些问题,支持者有一个松弛的通道,你可以找到一个比我更喜欢这种情况的程序员,你知道吗可能会觉得有帮助