xUnit.net在各测试方法/类中共享上下文
首先明确一点:xUnit框架会为每个test类中的test方法创建一个实例,也就是说有多少个[Fact]或[Theory]特性标注的方法,该类就会被实例化多少个,所以可以把共用的初始化代码放到测试类的构造函数里,构造函数里的代码同样会执行多次。
如果想要一次初始化后提供给各个测试使用,xUnit提供了对应两种依赖注入生命周期Scope和Singleton的方式:IClassFixture和ICollectionFixture
新建Fixture类,实现IDisposable接口并将需要共享的内容暴露出来:
public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new SqlConnection("MyConnectionString");
// ... initialize data in the test database ...
}
public void Dispose()
{
// ... clean up test data from the database ...
}
public SqlConnection Db { get; private set; }
}
然后在Test类实现IClassFixture接口并带有泛型的类型:
public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
DatabaseFixture fixture;
public MyDatabaseTests(DatabaseFixture fixture)
{
this.fixture = fixture;
}
// ... write tests, using fixture.Db to get access to the SQL Server ...
}
如此一来,在Test类第一次运行前,xUnit会创建Fixture类的实例,并在每次Test类实例化时将其传递进构造函数。显然这是Scope的生命周期。若要实现整个测试项目Singleton的生命周期,xUnit有ICollectionFixture:
新建一个类实现ICollectionFixture泛型接口并添加特性:
[CollectionDefinition("Database collection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
上一个方法中说到的Fixture类不需要更改。Test类添加[Collection("Database collection")]特性,去掉IClassFixture实现:
[Collection("Database collection")]
public class DatabaseTestClass1
{
DatabaseFixture fixture;
public DatabaseTestClass1(DatabaseFixture fixture)
{
this.fixture = fixture;
}
}
这样Collection同名的Test类就会共享定义中指定的Fixture类实例。
另外要注意的是:Fixture类会在测试类构造函数注入的时候实例化,因此Fixture中的构造函数的代码如果发生异常的话,会导致注入失败,测试类就根本没有实例化出来。此过程会发生异常,错误提示为
The following constructor parameters did not have matching fixture data
但不会在调试的时候提示,而是直接判定测试不通过,在测试管理器上显示结果。
xUnit.net官方文档:https://xunit.net/docs/shared-context.html
本文来自博客园,作者:pikqu,转载请注明原文链接:https://www.cnblogs.com/pikqu/p/12941029.html

浙公网安备 33010602011771号