我有一组测试用例,其中一些预计会抛出异常。因此,我已经设置了这些测试的属性,以期望这样的例外:
[ExpectedException("System.NullReferenceException")]
当我在本地运行测试时,一切都很好。但是,当我将测试移动到运行TeamCity的CI服务器时,所有具有预期异常的测试都会失败。这是一个已知的错误。
我知道NUnit还提供了Assert.Throws<>
和Assert.Throws
方法。
我的问题是如何使用这些而不是我目前正在使用的属性?
我已经浏览过StackOverflow并尝试了一些似乎对我没用的东西。
是否有一个简单的1行解决方案来使用它?
答案 0 :(得分:86)
我不确定你所尝试的是什么让你遇到麻烦,但你可以简单地传入一个lambda作为Assert.Throws的第一个参数。这是我通过的一项测试中的一项:
Assert.Throws<ArgumentException>(() => pointStore.Store(new[] { firstPoint }));
好的,这个例子可能有点冗长。假设我有一个测试
[Test]
[ExpectedException("System.NullReferenceException")]
public void TestFoo()
{
MyObject o = null;
o.Foo();
}
会正常传递,因为o.Foo()
会引发空引用异常。
然后,您将删除ExpectedException
属性并将您的电话打包到o.Foo()
中的Assert.Throws
。
[Test]
public void TestFoo()
{
MyObject o = null;
Assert.Throws<NullReferenceException>(() => o.Foo());
}
Assert.Throws
“尝试调用代表作为委托的代码片段,以验证它是否会抛出特定异常。” () => DoSomething()
语法表示 lambda ,本质上是一个匿名方法。因此,在这种情况下,我们告诉Assert.Throws
执行代码段o.Foo()
。
所以不,你不只是像你做一个属性一样添加一行;在调用Assert.Throws
时,您需要显式地包装将引发异常的测试部分。你不必必须使用lambda,但这通常是最方便的。
答案 1 :(得分:9)
这是一个使用两种方式的简单示例。
string test = null;
Assert.Throws( typeof( NullReferenceException ), () => test.Substring( 0, 4 ) );
Assert.Throws<NullReferenceException>( () => test.Substring( 0, 4 ) );
如果你不想使用lambdas。
[Test]
public void Test()
{
Assert.Throws<NullReferenceException>( _TestBody );
}
private void _TestBody()
{
string test = null;
test.Substring( 0, 4 );
}
答案 2 :(得分:2)
默认情况下,TeamCity使用NUnit 2.2.10,它没有ExpectedException。检查TeamCity“NUnit for NAnt”文档,了解如何将其更改为更现代的内容,包括TeamCity提供的特定发布列表。
答案 3 :(得分:0)
NUnit添加了一个新的Record.Exception方法。
如果您希望将行为与断言分开,则
行为:
ex = Record.Exception(()={throw new Exceprtion()}
声明:
Assert.NotNull(ex);