跳过通用测试类中特定类型的测试方法

时间:2015-04-16 06:29:39

标签: c# unit-testing generics nunit

我正在尝试对项目的一部分进行单元测试;我正在使用NUnit。目标单元处理多种类型的对象,所有类型都扩展了基本类型。我已经创建了一个通用测试类,我在其上设置了所需的测试类型:

[TestFixture(typeof(SomeType))]
[TestFixture(typeof(SomeOtherType))]
class MyTestClass<T> where T : SomeBaseType, new()
{

     [Test]
     public void DoThisTest()
     {
         var sut = CreateSut();
         var target = CreateTarget();

         Assert.IsTrue(sut.Process(target));
     }  

     [Test]
     public void DoThatTest()
     {
         var sut = CreateSut();
         var target = CreateInvalidTarget();

         Assert.IsFalse(sut.IsValid(target));
     }  

     //...
}

这将使用TestFixture为每个类型集创建一组所有测试。无论出于何种原因,我都有一个只在特定类型的上下文中有意义的测试。这意味着我需要1)在所有其他类型上使用Assert.Ignore()或2)为那些“特殊”测试用例创建一个不同的测试类。

有没有办法从外部选择测试(属性?)并指定在特定情况下不能“实施”特定测试?我想“结合”1)&amp; 2)使得所有测试用例都在同一个文件/类中,但是某些测试仅针对TestFixture设置的某些值进行渲染/实现/运行。

1 个答案:

答案 0 :(得分:1)

这并不是您正在寻找的,但我认为这是一个非常接近的工作。您可以在主测试夹具中指定嵌套类,并使用不同的TestFixture属性对其进行装饰,以限制运行的内容。它可能最好用一个例子来解释。因此,给定这些数据类型:

public interface ICompetitor {
    string GetFinalPosition();
}


public class Winner : ICompetitor{
    public string GetFinalPosition() {
        return "Won";
    }
}

public class Loser : ICompetitor {
    public string GetFinalPosition() {
        return "Lost";
    }
}

我可以定义这些TestFixtures:

[TestFixture(typeof(Winner))]
[TestFixture(typeof(Loser))]
public class CompetitorTests<T> where T : ICompetitor, new()
{
    static private T CreateSut() {
        return new T();
    }

    [Test]
    public void EverybodyHasPosition() {
        Assert.IsNotNullOrEmpty(CreateSut().GetFinalPosition());
    }

    [TestFixture(typeof(Winner))]
    public class WinnerTests {
        [Test]
        public void TestWon() {
            Assert.AreEqual("Won", CompetitorTests<T>.CreateSut().GetFinalPosition());
        }
    }

    [TestFixture(typeof(Loser))]
    public class LoserTests {
        [Test]
        public void TestLost() {
            Assert.AreEqual("Lost", CompetitorTests<T>.CreateSut().GetFinalPosition());
        }
    }
}

EverybodyHasPosition测试运行两次(Winner一次,Loser类一次)。 TestWon仅针对Winner类运行,TestLost仅针对Loser类运行。它并不理想,因为你只能访问外部类的静态成员,每个夹具都负责它自己的设置/拆卸。

通过使用基类,您可以解决这个问题。因此,状态共享版本看起来可能更像这样(注意每个TestFixture都继承自CompetitorTestsState):

public class CompetitorTestsState<T> where T : ICompetitor, new()  {
    protected T SUT { get; private set; }

    [SetUp]
    public void Setup() {
        SUT = CreateSut();
    }

    private T CreateSut() {
        return new T();
    }
}

[TestFixture(typeof(Winner))]
[TestFixture(typeof(Loser))]
public class CompetitorTests<T> : CompetitorTestsState<T> where T : ICompetitor, new() {
    [Test]
    public void EverybodyHasPosition() {
        Assert.IsNotNullOrEmpty(SUT.GetFinalPosition());
    }

    [TestFixture(typeof(Winner))]
    public class WinnerTests : CompetitorTestsState<T>{
        [Test]
        public void TestWon() {
            Assert.AreEqual("Won", SUT.GetFinalPosition());
        }
    }

    [TestFixture(typeof(Loser))]
    public class LoserTests : CompetitorTestsState<T>{
        [Test]
        public void TestLost() {
            Assert.AreEqual("Lost", SUT.GetFinalPosition());
        }
    }
}