NSubstitute中的TargetInvocationException

时间:2013-10-14 13:23:09

标签: c# testing nsubstitute targetinvocationexception

我想写一个测试检查,我的抽象类构造函数是否正确处理无效参数。我写了一个测试:

[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void MyClassCtorTest()
{
    var dummy = Substitute.For<MyClass>("invalid-parameter");
}

此测试未通过,因为NSubstitute会抛出TargetInvocationException而不是ArgumentException。我寻求的实际例外实际上是InnerException的{​​{1}}。我可以编写一个辅助方法,如:

TargetInvocationException

但我想,应该有某种解决这个问题的一般方法。有吗?

1 个答案:

答案 0 :(得分:2)

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)));
    }
相关问题