如果我有以下代码:
[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的类派生出来的?
答案 0 :(得分:9)
你必须直接调用这个方法。
[SetUp]
public void DerivedSetUp()
{
base.BaseSetUp();
// Do something else
}
编辑:我没有尝试过,但也许部分方法也可能有效。我宁愿做上面的事情。
Edit2:我刚尝试使用部分方法。它没用。即使它确实如此,我认为调用基类仍然会更容易。
答案 1 :(得分:3)
您明确拥有基类。鉴于NUnit使用[Setup]属性标记测试设置,我认为这对NUnit来说是“正确的事”,因为它遵循通常的语言规则。
当然,NUnit可以搜索基类,并自动调用它们的安装功能,但我认为这对大多数人来说都是相当令人惊讶的。
但是至少有一个单元测试框架使用构造函数进行设置:xUnit.Net。这里,基类设置是自动调用,因为这是C#中构造函数的行为。
(但请注意,xUnit.Net建议再次使用测试设置。)
答案 2 :(得分:1)
看起来您希望在任何测试开始之前运行一次设置,而不是在每次测试运行之前运行一次。注释[SetUp]使方法在运行夹具中的每个测试之前运行一次。 [SetUp]不是继承的。
您要使用的注释是[TestFixtureSetUp],在运行灯具中的任何测试之前,它只运行一次。这是以您期望的方式继承的。 :)
答案 3 :(得分:0)
我在Tampa的TDD FireStarter中学到的一种方法是在基类中使用setup方法,然后在基类中使用名为observe的虚方法。然后在setup方法结束时在基类中调用此方法。
然后你要做的是从基类派生的新类,你将覆盖observe方法。这种情况下的技巧是你想要执行基类的Setup方法,而子类没有Setup方法。原因是您在observe方法中拥有的代码只是子测试类所需的其他内容。
这种方法对我很有用,但有一个问题是测试运行器会想要执行基类测试,所以我要做的就是将测试从基类移动到派生的新类中如果我有的话,从基地开始。
答案 4 :(得分:-1)
以下适用于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.
}
}