NUnit SetUp中的ExpectedException

时间:2010-11-19 08:44:52

标签: c# unit-testing nunit

我正在使用NUnit和Rhino Mocks。我使用AAA语法,我在setup方法中执行Arrange和Act,每个Test方法都是Assert。

[TestFixture]
public class When_subSystem_throws_exception
{
    SomeClass subject; // System under test

    [SetUp]
    public void Setup()
    {
        // Arrange
        IDependency dependency = MockRepository.GenerateStub<IDependency>();
        dependency.Stub(m => m.DoStuff()).Throw(new Exception()); // This method is called from within SomeMethod()

        subject = new SomeClass(dependency);

        // Act
        subject.SomeMethod("Invalid Input");
    }

    // Assert

    [Test]
    public void should_log_an_exception_to_the_logger()
    {
        // Do stuff to verify that an exception has been logged
    }

    // More tests
}

正如您所料,SomeMethod()中的代码会抛出异常(如预期的那样),这会使每个测试失败(不需要)。我通过

来解决这个问题
try
{
    // Act
    subject.SomeMethod("Invalid Input");
}
catch(Exception ex)
{
    // Swallow, this exception is expected.
}

但那只是丑陋。

我希望能够做的是

[SetUp]
[ExpectedException]  // <-- this works for Test methods, but not for SetUp methods
public void Setup()
{
    // etc...
}

但我找不到类似的东西。

你知道什么吗?

3 个答案:

答案 0 :(得分:2)

由于某种原因,它在安装程序中不起作用,而不是因为NUnit的错误。

单元测试在SetUp方法中抛出异常是一种非常糟糕的做法。如果您正在测试异常是预期结果的特定方案,则应在[Test]方法内完成。您应该随后重新安排代码。

答案 1 :(得分:2)

我不认为使用像ExpectedException这样的属性是一个好主意。 SetUp是为测试方法准备一些东西,它不应该抛出异常。 如果必须抛出,并且您想限制代码行号。然后把它们放在一行如下:

try { subject.SomeMethod("Invalid Input"); }catch { }

答案 2 :(得分:1)

您的“行为”步骤应该是测试方法,而不是设置。

该设置用于设置测试的先决条件和常用对象 - 即共同或重复的“排列”步骤。

每种测试方法都应单独“行动”和“断言”(并且可能还需要针对测试的其他“安排”步骤。)