在 xUnit 中管理多级收集装置/从 NUnit 移植
Managing multiple levels of collection fixtures in xUnit / porting from NUnit
我们目前正在将 NUnit 测试迁移到 xUnit。在我们之前的测试中,我们有多个级别的测试基地:
public class TestBase {
protected ICacheManagerFactory _cacheManagerFactory;
[OneTimeSetup]
public void OneTimeSetup()
{
//Setup code
}
}
public class ControllerTestBase : TestBase {
[OneTimeSetup]
public void OneTimeSetup()
{
//Setup code
_cacheManagerFactory.SomeSetup();
}
}
我们想在 xUnit 中复制该功能,这样原始的 TestBase 设置就不会 运行 多次。我们正在尝试像这样在集合中使用集合:
public sealed class CollectionFixtureBase {
public ICacheManagerFactory CacheManagerFactory;
public CollectionFixtureBase
{
//Setup code
}
}
[Collection("CollectionFixtureBase")]
public sealed class ControllerCollectionFixture {
public CollectionFixtureBase CollectionBase;
public ControllerCollectionFixture(CollectionFixtureBase collectionBase)
{
CollectionBase = collectionBase
CollectionBase.CacheManagerFactory.SomeSetup();
}
}
(为简洁起见,我省略了集合夹具定义)
但是,当我们 运行 这段代码时,我们遇到了依赖注入错误:
System.AggregateException : One or more errors occurred.
Collection fixture type 'Instanda.UnitTests.New.Collections.ControllerCollectionFixture' had one or more unresolved constructor arguments: CollectionFixtureBase collectionFixture
The following constructor parameters did not have matching fixture data: ControllerCollectionFixture collectionFixture
我们是不是走错了路?我们可以从基础 类 继承,但我的印象是这会导致基础代码多次 运行?是否有其他方法来获得此功能?
当试图理解 CollectionFixture
作为新手时(尤其是在 NUnit、JUnit 和其他系统中有经验的人,这些系统往往会导致测试 Classes 中的 class 层次结构),我建议在 https://xunit.net/docs/shared-context 上进行大量传球;该模型非常不同且微妙。好的,现在你从那里回来了:TL;DR
xUnit Collection Fixtures 实现的主要目的是确保一次只有一个测试可以使用共享的东西
xUnit 管理它们:
一个。让他们(一次)
b。在每次测试 运行 之前通过 IUse
* 将它们传递给您的测试 class(记住 NUnit 和 xUnit 之间的关键区别在于每次 Fresh Fixture
在不再classes/tests需要它们时处理它们
就是这样 - 没有 class 等级等
而 Collection Fixtures 是最强大的构造,很难手动编写,并且相对常见,例如包装数据库,不要忘记 Class Fixtures - 它们是典型的 OneTimeSetup
的工作马,就像在 OP
在对如何跨测试 Classes 管理共享装置进行高级分解时,您要做的主要事情是让尽可能多的东西 运行 并发和独立( xUnit 运行s multiple Test Classes default concurrently; Collection Fixtures is the key way to constrain this)
在使用 NUnit 模式和 OneTimeSetup
/Setup
/Teardown
属性获得的典型 class 层次结构之间进行迁移时,一般高级建议:
- 尝试将辅助逻辑拆分为单独的 Fixture,以清晰的方式管理一个方面;通常在 NUnit 中,您的灯具会倾向于 'blend'
- 你在 base classes 中使用 NUnit 所做的大多数事情映射到 xUnit 中的 Class fixtures(xUnit 在每次测试之前制作并提供给测试 Class)
- stuff 绝对只能是通常映射到 Collection Fixtures 中的一个
- advanced/rare:对于可以安全共享的任何其他助手,通常使用 Class 固定装置,其中一些静态方面由静态 ctor 或其他一些守卫初始化以管理并发 initialisation/access 安全状态
- 它绝对不是非法的,但应该成为一种非常罕见的情况,你最终使用基础 classes 进行测试(你将东西放在构造函数中并
IDisposable.Dispose
替换设置和拆卸方法)
我们目前正在将 NUnit 测试迁移到 xUnit。在我们之前的测试中,我们有多个级别的测试基地:
public class TestBase {
protected ICacheManagerFactory _cacheManagerFactory;
[OneTimeSetup]
public void OneTimeSetup()
{
//Setup code
}
}
public class ControllerTestBase : TestBase {
[OneTimeSetup]
public void OneTimeSetup()
{
//Setup code
_cacheManagerFactory.SomeSetup();
}
}
我们想在 xUnit 中复制该功能,这样原始的 TestBase 设置就不会 运行 多次。我们正在尝试像这样在集合中使用集合:
public sealed class CollectionFixtureBase {
public ICacheManagerFactory CacheManagerFactory;
public CollectionFixtureBase
{
//Setup code
}
}
[Collection("CollectionFixtureBase")]
public sealed class ControllerCollectionFixture {
public CollectionFixtureBase CollectionBase;
public ControllerCollectionFixture(CollectionFixtureBase collectionBase)
{
CollectionBase = collectionBase
CollectionBase.CacheManagerFactory.SomeSetup();
}
}
(为简洁起见,我省略了集合夹具定义)
但是,当我们 运行 这段代码时,我们遇到了依赖注入错误:
System.AggregateException : One or more errors occurred. Collection fixture type 'Instanda.UnitTests.New.Collections.ControllerCollectionFixture' had one or more unresolved constructor arguments: CollectionFixtureBase collectionFixture The following constructor parameters did not have matching fixture data: ControllerCollectionFixture collectionFixture
我们是不是走错了路?我们可以从基础 类 继承,但我的印象是这会导致基础代码多次 运行?是否有其他方法来获得此功能?
当试图理解 CollectionFixture
作为新手时(尤其是在 NUnit、JUnit 和其他系统中有经验的人,这些系统往往会导致测试 Classes 中的 class 层次结构),我建议在 https://xunit.net/docs/shared-context 上进行大量传球;该模型非常不同且微妙。好的,现在你从那里回来了:TL;DR
xUnit Collection Fixtures 实现的主要目的是确保一次只有一个测试可以使用共享的东西
xUnit 管理它们:
一个。让他们(一次)
b。在每次测试 运行 之前通过
IUse
* 将它们传递给您的测试 class(记住 NUnit 和 xUnit 之间的关键区别在于每次 Fresh Fixture在不再classes/tests需要它们时处理它们
就是这样 - 没有 class 等级等
而 Collection Fixtures 是最强大的构造,很难手动编写,并且相对常见,例如包装数据库,不要忘记 Class Fixtures - 它们是典型的 OneTimeSetup
的工作马,就像在 OP
在对如何跨测试 Classes 管理共享装置进行高级分解时,您要做的主要事情是让尽可能多的东西 运行 并发和独立( xUnit 运行s multiple Test Classes default concurrently; Collection Fixtures is the key way to constrain this)
在使用 NUnit 模式和 OneTimeSetup
/Setup
/Teardown
属性获得的典型 class 层次结构之间进行迁移时,一般高级建议:
- 尝试将辅助逻辑拆分为单独的 Fixture,以清晰的方式管理一个方面;通常在 NUnit 中,您的灯具会倾向于 'blend'
- 你在 base classes 中使用 NUnit 所做的大多数事情映射到 xUnit 中的 Class fixtures(xUnit 在每次测试之前制作并提供给测试 Class)
- stuff 绝对只能是通常映射到 Collection Fixtures 中的一个
- advanced/rare:对于可以安全共享的任何其他助手,通常使用 Class 固定装置,其中一些静态方面由静态 ctor 或其他一些守卫初始化以管理并发 initialisation/access 安全状态
- 它绝对不是非法的,但应该成为一种非常罕见的情况,你最终使用基础 classes 进行测试(你将东西放在构造函数中并
IDisposable.Dispose
替换设置和拆卸方法)