TargetInvocationException in NSubstitute
本文关键字:NSubstitute in TargetInvocationException | 更新日期: 2023-09-27 18:35:20
我想写一个测试来检查我的抽象类构造函数是否正确处理无效参数。我写了一个测试:
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void MyClassCtorTest()
{
var dummy = Substitute.For<MyClass>("invalid-parameter");
}
此测试未通过,因为 NSubstitute 抛出TargetInvocationException
而不是ArgumentException
。我寻求的实际例外实际上是该TargetInvocationException
的InnerException
。我可以编写一个帮助程序方法,例如:
internal static class Util {
public static void UnpackException(Action a) {
try {
a();
} catch (TargetInvocationException e) {
throw e.InnerException;
} catch (Exception) {
throw new InvalidOperationException("Invalid exception was thrown!");
}
}
}
但我想,应该有某种通用的方法来解决这个问题。有吗?
NSubstitute目前没有解决这个问题的通用方法。
其他一些解决方法包括手动子类化抽象类以测试构造函数,或者手动断言内部异常而不是使用 ExpectedException
。
例如,假设我们有一个需要非负整数的抽象类:
public abstract class MyClass {
protected MyClass(int i) {
if (i < 0) {
throw new ArgumentOutOfRangeException("i", "Must be >= 0");
}
}
// ... other members ...
}
我们可以在测试夹具中创建一个子类来测试基类构造函数:
[TestFixture]
public class SampleFixture {
private class TestMyClass : MyClass {
public TestMyClass(int i) : base(i) { }
// ... stub/no-op implementations of any abstract members ...
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestInvalidConstructorArgUsingSubclass()
{
new TestMyClass(-5);
}
// Aside: I think `Assert.Throws` is preferred over `ExpectedException` now.
// See http://stackoverflow.com/a/15043731/906
}
或者,您仍然可以使用模拟框架并断言内部异常。我认为这不如以前的选项可取,因为不清楚我们为什么要深入研究TargetInvocationException
,但无论如何这里有一个例子:
[Test]
public void TestInvalidConstructorArg()
{
var ex = Assert.Throws<TargetInvocationException>(() => Substitute.For<MyClass>(-5));
Assert.That(ex.InnerException, Is.TypeOf(typeof(ArgumentOutOfRangeException)));
}