使用 NUnit 在派生类中进行设置?

发布于 2024-07-14 01:57:53 字数 1271 浏览 3 评论 0原文

如果我有以下代码:

[TestFixture]
public class MyBaseTest
{
    protected ISessionManager _sessionManager;

    [SetUp]
    public void SetUp() { /* some code that initializes _sessionManager */ }
}

[TestFixture]
public class MyDerivedTest : MyBaseTest
{
    IBlogRepository _repository;

    [SetUp]
    public void SetUp() { /* some code that initializes _repository */ }

    [Test]
    public void BlogRepository_TestGoesHere() { /* some tests */ }
}

...NUnit 不会调用基本 SetUp 例程。 这是预料之中的,我对此本身没有问题。 我可以让派生的 SetUp 首先调用基本 SetUp,如下所示:

[TestFixture]
public class MyDerivedTest : MyBaseTest
{
    IBlogRepository _repository;

    [SetUp]
    public new void SetUp()
    {
        base.SetUp();
        /* some code that initializes _repository */
    }

这很丑陋。 如果它是一个构造函数,我就不必这样做。

我可以使用“模板方法”模式,并具有以下内容:

public void MyBaseTest
{
    abstract void SetUp();

    [SetUp]
    public void BaseSetUp()
    {
        /* base initialization */
        SetUp(); // virtual call
    }
}

我也不是特别喜欢这个。

当他们的测试类需要 SetUp,并且它们派生自另一个也需要 SetUp 的类时,您该怎么办?

If I have the following code:

[TestFixture]
public class MyBaseTest
{
    protected ISessionManager _sessionManager;

    [SetUp]
    public void SetUp() { /* some code that initializes _sessionManager */ }
}

[TestFixture]
public class MyDerivedTest : MyBaseTest
{
    IBlogRepository _repository;

    [SetUp]
    public void SetUp() { /* some code that initializes _repository */ }

    [Test]
    public void BlogRepository_TestGoesHere() { /* some tests */ }
}

...NUnit doesn't call the base SetUp routine. This is expected, and I don't have a problem with it in itself. I can get the derived SetUp to call the base SetUp first, like this:

[TestFixture]
public class MyDerivedTest : MyBaseTest
{
    IBlogRepository _repository;

    [SetUp]
    public new void SetUp()
    {
        base.SetUp();
        /* some code that initializes _repository */
    }

This is ugly. If it was a constructor, I wouldn't have to.

I could use the "template method" pattern, and have the following:

public void MyBaseTest
{
    abstract void SetUp();

    [SetUp]
    public void BaseSetUp()
    {
        /* base initialization */
        SetUp(); // virtual call
    }
}

I'm not particularly fond of this, either.

What do you do when their test classes need SetUp, and they're derived from another class that also needs SetUp?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

£噩梦荏苒 2024-07-21 01:57:53

您必须直接调用该方法。

   [SetUp]
   public void DerivedSetUp()
   {
      base.BaseSetUp();
      // Do something else
   }

编辑:我还没有尝试过,但也许部分方法也可能有效。 但我更愿意执行上述操作。

Edit2:我刚刚尝试使用部分方法。 它不起作用。 即使确实如此,我认为调用基类仍然会更容易。

You have to call the method directly.

   [SetUp]
   public void DerivedSetUp()
   {
      base.BaseSetUp();
      // Do something else
   }

Edit: I haven't tried it, but perhaps a partial method might work too. I'd prefer to do the above though.

Edit2: I've just tried using partial methods. It didn't work. Even if it did, I think it's still going to be easier to call the base class.

瞎闹 2024-07-21 01:57:53

您明确拥有基类。 鉴于 NUnit 使用 [Setup] 属性来标记测试设置,我认为这对于 NUnit 来说是“正确的事情”,因为它遵循通常的语言规则。

当然,NUnit 可以搜索基类,并自动调用它们的设置函数,但我认为这对大多数人来说是相当令人惊讶的。

然而,至少有一个使用构造函数进行设置的单元测试框架:xUnit.Net。 这里,自动调用基类设置,因为这是 C# 中构造函数的行为方式。

(但请注意,xUnit.Net 建议再次使用测试设置。)

You have the base class explicitly. Given that NUnit uses the [Setup] attribute to mark up test setup, I tink this is "the right thing" to do for NUnit, because it follows the usual language rules.

Sure, NUnit could search the base classes, and call their Setup functions automagically, but I think this would be rather surprising for most people.

There is however at least one unit testing framework that uses constructors for setup: xUnit.Net. Here, the base class setup is called automatically, because this is how constructors in C# behave.

(Note, though, that xUnit.Net recommends again using test setup.)

花辞树 2024-07-21 01:57:53

看起来您希望在任何测试开始之前运行一次安装程序,而不是在每个测试运行之前运行一次。 注释 [SetUp] 使该方法在运行装置中的每个测试之前运行一次。 [SetUp] 不被继承。

您要使用的注释是 [TestFixtureSetUp],它仅在运行夹具中的任何测试之前运行一次。 这是按照您所期望的方式继承的。 :)

请参阅TextFixtureSetUp 文档

It looks like you want the setup to be run once before any testing starts, not once before each test is run. The annotation [SetUp] makes the method run once before each test in your fixture is run. [SetUp] is not inherited.

The annotation you want to use is [TestFixtureSetUp] which is run only once, before any of the tests in a fixture are run. This is inherited in the way that you would expect. :)

See the TextFixtureSetUp docs

み格子的夏天 2024-07-21 01:57:53

我在坦帕的 TDD FireStarter 中学到的一种方法是在基类中使用 setup 方法,然后在基类中使用一个名为observe 的虚拟方法。 然后在基类中的 setup 方法末尾调用此方法。

然后您要做的就是在从基类派生的新类中重写观察方法。 这种情况下的技巧是您想要执行基类的Setup 方法,而子类没有Setup 方法。 原因是您在观察方法中拥有的代码只是子测试类所需的附加内容。

这种方法对我来说效果很好,但一个问题是测试运行者想要执行基类测试,所以我要做的就是将测试从基类移动到派生自基类的新类中如果我有的话。

An approach that I use that I learned in the TDD FireStarter in Tampa was to have the setup method in the base class and then to have a virtual method in the base class called observe. This method is then called in the base class at the end of the setup method.

Then what you do is in the new class that derives from the base class you will override the observe method. The trick in this scenario is you want to execute the Setup method of the base class and the child class does not have a Setup method. The reason for this is the code that you have in the observe method are only those additional things you need for the child test class.

This approach works well for me, but one gotcha is that the test runner will want to execute the base class tests, so what I do to get around that is to move the Tests from the base class into a new class that derives from the base if I have any.

梦言归人 2024-07-21 01:57:53

以下在 MbUnit 中有效。 它也可以在 NUnit 中工作。

[TestFixture]
public abstract class Base {
    [SetUp]
    public virtual void SetUp() {
        //Some stuff.
    }
}

public class Derived : Base {
    public override void SetUp() {
        base.SetUp();
        //Some more stuff.
    }
    [Test]
    public virtual void Object_WhenInACertainState_WhenAMethodIsCalled_Throws() {
        //Create and set state on the object.
        //Call the method.
        //Assert the method threw.
    }
}

The following works in MbUnit. It may work in NUnit as well.

[TestFixture]
public abstract class Base {
    [SetUp]
    public virtual void SetUp() {
        //Some stuff.
    }
}

public class Derived : Base {
    public override void SetUp() {
        base.SetUp();
        //Some more stuff.
    }
    [Test]
    public virtual void Object_WhenInACertainState_WhenAMethodIsCalled_Throws() {
        //Create and set state on the object.
        //Call the method.
        //Assert the method threw.
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文