集合 fixture 无法注入

20
我正在使用 xUnit 2.0 的 集合夹具 来在多个不同的测试类之间共享一个通用的数据库设置和清理。该夹具还提供了一些帮助属性,因此我将其注入到每个测试类中。

我按照文档中的示例进行了重现,但是当我运行测试时,它立即失败并显示:

  

以下构造函数参数没有匹配的夹具数据: IntegrationTestFixture fixture

这似乎无论我是使用 xUnit Facts 还是 Theories,或者使用哪个测试运行器都会发生。


夹具:

public class IntegrationTestFixture : IDisposable
{
    public IntegrationTestFixture()
    {
        // (setup code)
        this.GeneratedTestName = [randomly generated];
    }

    public void Dispose()
    {
        // (teardown code)
    }

    public string GeneratedTestName { get; private set; }
}

收藏品定义:

[CollectionDefinition("Live tests")]
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFixture>
{
    // Intentionally left blank.
    // This class only serves as an anchor for CollectionDefinition.
}

测试:

[CollectionDefinition("Live tests")]
public class SomeTests
{
    private readonly IntegrationTestFixture fixture;

    public SomeTests(IntegrationTestFixture fixture)
    {
        this.fixture = fixture;
    }

    [Fact]
    public void MyTestMethod()
    {
        // ... test here
    }
}
9个回答

27

这是一个愚蠢的错误,我花了一点时间才弄清楚为什么它不起作用:

[CollectionDefinition]应该放在集合定义类上,而[Collection]应该放在测试类上。我当时习惯性地犯了这个错误,没有注意到这点。

如果在不同的类中有多个具有相同名称的[CollectionDefinition]属性,您也会遇到此问题。只需使用一个即可!


我非常依赖自动驾驶模式,谢谢!你节省了我的时间 :) - akrsmv

8

如果您的集合构造函数抛出错误,也会出现这种情况。在这种情况下,您可能需要通过其他方式调试该代码,因为xUnit提供的错误消息并不有用。


我也赞同这个观点,我忘记在实体中初始化一个集合,结果得到了与 OP 相同的错误。 - BartKrul

8

在我的情况下,夹具和集合位于共享测试程序集中。我发现XUnit DI无法找到它。因此,我不得不定义一个夹具,该夹具继承了共享程序集中的这些类,以同时共享功能并在我的测试类中注册它。


4
遇到了相同的问题。在collection-fixture页面下已经说明了这一点。 重要提示:夹具可以在程序集之间共享,但集合定义必须与使用它们的测试位于同一个程序集中。 - Patrick

7

我曾经遇到过同样的错误,但我的问题是我忘记把CollectionDefinition类设置为public

错误的示例:

[CollectionDefinition("Live tests")]
class IntegrationTestCollection : ICollectionFixture<IntegrationTestFixture>
{
    // Intentionally left blank.
    // This class only serves as an anchor for CollectionDefinition.
}

正确

[CollectionDefinition("Live tests")]
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFixture>
{
    // Intentionally left blank.
    // This class only serves as an anchor for CollectionDefinition.
}

5

在我的情况下,我忘记继承 IClassFixture 接口...

错误的做法...

public class DatabaseIntegrationTests
{

正确的代码应该是:

public class DatabaseIntegrationTests : IClassFixture<DatabaseFixture>
{

很遗憾,这并不是解决问题的方法。在这种情况下,您只是让所有的类每次使用一个新的“DatabaseFixture”实例。在夹具构造函数中插入断点,并查看它被命中的次数。 - Tom Makin
这让我再次检查; 这导致我发现我自动完成了 ICollectionFixture 而不是 IClassFixture - Aaron
集合的装置与类的装置不同。 - DCShannon

1
许多我们的测试夹具类名称相似。因此,请确保定义中的测试夹具类型与包含测试的类构造函数中传递的类型完全匹配。

0

我刚遇到这个问题,不得不将集合定义放在与测试类相同的命名空间中,而不仅仅是相同的程序集。


0

根据这个问题:

如果您有多个测试项目,每个项目都应该有自己的FixtureCollection

您不能在项目之间使用共享的FixtureCollection

明确一下,我认为存在的 bug 是我们只在测试程序集中搜索集合定义,而不是在所有程序集中搜索。

这并不意味着我们支持跨测试程序集的单个集合 fixture 实例。每个测试程序集都在其自己的 App Domain 中运行隔离。您仍然可以在每个 App Domain 中获得集合 fixture 的新实例。


0
在我的情况下,我有两个类库。
Tests.Infrastructure.csproj

而且

Tests.Web.csproj

Database fixture 存储在 Tests.Web.csproj 中的测试无法注入。 Fixture 实现在第二个类库中,即 Tests.Infrastructore.csproj

我将 fixture 的实现移动到了 Tests.Web.csproj 中,删除了 Infrastructure,现在一切都正常了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接