【问题标题】:xUnit - Using Context from SetFixture() In the Test Class ConstructorxUnit - 在测试类构造函数中使用来自 SetFixture() 的上下文
【发布时间】:2014-07-02 11:41:59
【问题描述】:

编辑:问题已修改。

我正在将几个测试从 nUnit 迁移到 xUnit,并且我有一个问题要重新评估 SetFixture() 方法和构造函数之间的关系。 我的测试有通用的设置方法。根据 xUnit 手册,[Setup] 代码现在应该进入构造函数。考虑这个例子:

public class MyTestClass : IUseFixture<TestFixture> {

    private TestObject m_MyObject;

    public MyTestClass() {
        m_MyObject.Login()
    }

    public void SetFixture(TestFixture data) {
        m_MyObject = data.TestObject;
    }

    [Fact]
    public void MyTest() {
        Console.Writeline("My Test");
    }

TestObject 在我的 Fixture 类上被初始化一次。在SetFixture() 中,我将其分配给本地成员,以便测试代码可以使用它。但是,我也在安装过程中使用了这个对象。作为在SetFixture() 之前运行的构造函数,我无法使用我的TestObject。该问题的解决方案是什么?

【问题讨论】:

  • 对特定代码的一种简化是完全停止维护m_MyObject - 只需将SetFixture() 更改为data.Login()。但我猜你也在做其他事情。如果你是,也许你可以做类似_context = data.Login() 的事情来清理和简化逻辑? (或者放弃这个想法,你可以在你的测试的基类中实现IUseFixture&lt;TestFixture&gt;:D)
  • 已编辑答案以对您更新的问题做出完整答复。随意修改您的问题,就像您在第一个实例中询问第二个表格一样。
  • 谢谢鲁本。该问题已按照您的建议进行了修改。

标签: unit-testing integration-testing xunit xunit.net


【解决方案1】:

编辑:从漫无边际的初始响应中进行了大量编辑 - 前两个 cmets(来自 OP 和我)已被编辑过时。


您在 xUnit v1 IUseFixture 机制的设计中遇到了一个弱点,该机制通常适用于使用 Setter 方法注入 [the excellent Dependency Injection in .NET book] 中记录的模式。 (见相关discussion in context of same patterns in Ninject

ctor 和 SetFixture 确实在每个测试中调用一次。通常,您不应该在 SetFixture 中执行任何操作,而不是存储值。 Fixture 的 ctor 是进行任何与 Fixture 相关的设置的地方(显然这只会发生一次)。

我倾向于将我的测试类设为静态,然后依靠AutoFixture.xUnit 来避免SetFixture 和/或有状态的测试类,但这可能适合也可能不适合您的情况。

在 xUnit v2 中,您可以将 Fixtures 作为参数添加到 Test Class 构造函数,这将避免您遇到的问题。这种机制在与 C# 6 新的主构造函数机制结合使用时也特别好(显然 F# 就像一切一样:)

【讨论】:

  • @TomZ 您遇到了 Setter Method Injection[1] 的关键问题之一。您的 [更新] 问题是在 ctor 中尽可能多地做事情的一般规则的必要例外,这是由您引用的不可克服的排序问题带来的,这促使您走向测试设置方法 Warren 反模式。在 xUnit 中拥有适当的 ctor 注入支持将简化您的案例(我的许多案例也是如此 - 虽然老实说,AutoFixture.xUnit 是我让这样的痛苦消失的锤子)。 [1] 尽快获取Dependency Injection in .NET,很棒的书
  • v2 中的 Fixtures 是通过构造函数注入而不是 setter 注入提供的。它不太明显(v1 中的旧接口要求您编写 setter 方法),但它也更有用,因为这意味着您可以一次访问所有固定装置。
  • @BradWilson 感谢您的确认(我扫描了 xUnit 项目的问题通知,并有一个模糊的想法是这种情况)。已经编辑了我的答案,好像我一直都知道这一点并且有完美的回忆:D
  • 谢谢鲁本和布拉德。我认为在 xUnit V2 向公众发布之前,我要么将一些安装代码添加到SetFixture(),要么尝试一下看起来很有趣的 AutoFixture.xUnit。谢谢!
  • @Tom Z 很公平(记住它在 NuGet 中,您只需要包括预发行版)。我应该提到的一件事是 AutoFixture.xUnit 不包括任何内在的共享固定装置机制(这对您的理智来说是一件好事)-我的 cmets 建议 a) 适用 b) 可以直接处理您的问题;这很容易出错(但 AutoFixture 非常适合测试代码库的可维护性和简洁性,因此值得花一些时间)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-30
  • 2020-03-02
  • 2019-01-10
  • 1970-01-01
相关资源
最近更新 更多