我正在构建一个具有一些公共和私有方法的类库.我希望能够对私有方法进行单元测试(主要是在开发时,但它也可能对将来的重构有用).
这样做的正确方法是什么?
Visual Studio允许通过自动生成的访问器类对私有方法进行单元测试.我编写了一个成功编译的私有方法的测试,但它在运行时失败了.一个相当小的代码和测试版本是:
//in project MyProj
class TypeA
{
private List<TypeB> myList = new List<TypeB>();
private class TypeB
{
public TypeB()
{
}
}
public TypeA()
{
}
private void MyFunc()
{
//processing of myList that changes state of instance
}
}
//in project TestMyProj
public void MyFuncTest()
{
TypeA_Accessor target = new TypeA_Accessor();
//following line is the one that throws exception
target.myList.Add(new TypeA_Accessor.TypeB());
target.MyFunc();
//check changed state of target
}
Run Code Online (Sandbox Code Playgroud)
运行时错误是:
Object of type System.Collections.Generic.List`1[MyProj.TypeA.TypeA_Accessor+TypeB]' cannot be converted to type …Run Code Online (Sandbox Code Playgroud) 我使用NUnit对C#中的私有方法进行单元测试.
例如,我的方法(如果是公共的)应该抛出一个ArgumentNullException.我可以声明该方法抛出ArgumentNullException如此:Assert.Throws<ArgumentNullException>(() => method.Call());
但是,因为我使用反射调用私有方法,所以我会断言一个TargetInvocationException抛出ArgumentNullException类似的方法:Assert.Throws<TargetInvocationException>(() => methodInfo.Invoke(obj, new object[] { params }));
我想声明一个ArgumentNullException而不是一个TargetInvocationException私有方法,所以我可以扫描它的代码,知道它的预期做什么而不是调试找出来.
我如何断言实际的异常,而不是TargetInvocationException?
注意:这个问题并没有解决单元测试公共与私有方法背后的理论.我和我的团队决定对私有方法进行单元测试,这是否是单元测试的方式与这个问题无关.请参阅此问题上最受欢迎的答案,以了解我们的理由.
如何使用反射(使用C#)测试抽象类的私有方法?我特别感兴趣的是调整这个帖子中的代码.
我知道关于首先测试私有代码的原则的讨论(一般不应该!).由于种种原因,我已经决定为我的情况做这件事,所以我们不要重复那些讨论.其他SO线程(如Q#1583363和1506427)详细讨论了它们.谢谢.