强制.NET测试方法从内部失败

时间:2013-11-21 14:02:24

标签: c# .net unit-testing

我的大多数测试方法首先尝试两到三个简单的操作,这些操作应引发异常,然后开始真正的工作。在Java中,我会这样写:

@Test
public void TestSomething() {

    try {
        testedClass.testedMethod(null);
        fail();
    catch (IllegalArgumentException ex) {
        // OK
    }

    // and now let's get to the point ...
    // ...

} 

我想在C#中坚持这种习惯,但似乎没有办法强迫测试方法失败。我已经看了一会儿,但没有运气。我错过了什么吗?

PS:我知道测试这些情况的正确方法是:

[TestMethod]
[ExpectedException(ArgumentNullException)]
public void TestSomethingWithNull() {

    testedClass.TestedMethod(null);

}

[TestMethod]
public void TestSomething() {

   // now the non-trivial stuff...

}

...但是,我不喜欢这个。当我有,比方说,我的测试类中的6个测试方法,并且每个测试应该从覆盖三个琐碎的,一行情况开始,这应该引发异常,使用这种方法将我的6个测试变成18个。应用程序,这确实污染了我的测试资源管理器并使结果更难以扫描。

让我们说我想测试一个方法,它的职责是验证某个类的给定实例的每个属性,并在任何值不正确时引发ValidationException。这可以通过一个TestValidation()测试轻松处理,但是使用这种方法,将其转换为:

  • TestValidationWithNull();
  • TestValidationWithInvalidProperty1();
  • TestValidationWithInvalidProperty2();
  • TestValidationWithNullProperty2();

想象一下,你有20个属性......:)

当然,如果这是唯一的方法,我会咬人。

3 个答案:

答案 0 :(得分:11)

您可以使用Assert.Fail()或抛出NotImplementedException(如果您正在测试的方法尚未实施)。

但是为了测试代码是否抛出异常,我建议你使用ExpectedException属性(如果你坚持使用MSTest) - 如果不抛出异常,测试将失败。

答案 1 :(得分:4)

你需要

Assert.Fail("Optional Message");

或者您可以从方法

中抛出异常

您还应该查看NUnit中的TestCase属性和TestCaseSource。这些可能会大大简化您的代码和当你想将不同的参数传递给测试时进行测试。

答案 2 :(得分:2)

为什么建议对所有“琐碎”的东西使用单独的测试方法的原因是因为测试方法早期的Assert.Fail()可能会隐藏后来的问题。正如你所说的那样,很多琐碎的测试方法都很快变得笨拙。

请记住,Asset.Equals(至少对于NUnit)可以比较数组。因此,您可以将测试更改为以下内容,并模拟测试测试项目的许多方面,同时了解所有结果:

public void TestSomething() 
{
    var result1 = false;
    try 
    {
        testedClass.testedMethod(null);
        result1 = true;
    }
    catch (IllegalArgumentException ex) { }

    var result2 = SomeDetailedTest();

    var expected = new Object[] { false, 42 };
    var actual =  new Object[] { result1, result2 };
    Assert.AreEqual(expected, actual);
}