我正在使用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...
}
但我找不到类似的东西。
你知道什么吗?
答案 0 :(得分:2)
由于某种原因,它在安装程序中不起作用,而不是因为NUnit的错误。
单元测试在SetUp方法中抛出异常是一种非常糟糕的做法。如果您正在测试异常是预期结果的特定方案,则应在[Test]方法内完成。您应该随后重新安排代码。
答案 1 :(得分:2)
我不认为使用像ExpectedException
这样的属性是一个好主意。
SetUp
是为测试方法准备一些东西,它不应该抛出异常。
如果必须抛出,并且您想限制代码行号。然后把它们放在一行如下:
try { subject.SomeMethod("Invalid Input"); }catch { }
答案 2 :(得分:1)
您的“行为”步骤应该是测试方法,而不是设置。
该设置用于设置测试的先决条件和常用对象 - 即共同或重复的“排列”步骤。
每种测试方法都应单独“行动”和“断言”(并且可能还需要针对测试的其他“安排”步骤。)