N替代测试是否调用了私有类的方法

时间:2019-02-16 14:19:39

标签: c# mocking nsubstitute

没有太多的测试经验,试图通过测试我最近制作的库来改变这种情况。

为此使用nunit代替nunit。

所以我遇到的情况是这样的:

class MyClassToTest {
    private ISomeOtherClass MyPrivateClass { get;set }

    public MyClassToTest() {
        MyPrivateClass = new SomeOtherClass();
    }

    public void DoSomething() {
        MyPrivateClass.SayHello();
    }
} 

现在,对DoSomething方法的测试将是查看SayHello()实例上是否实际上调用了方法ISomeOtherClass

问题在于它是私有的,当寻找最佳方法进行测试时,唯一出现的就是将属性设置为内部,并将InternalsVisibleToAttribute设置为测试所在的程序集。

>

虽然此解决方案有效并且我的库的外部接口仍然可以,但是在库的上下文中此属性的正确访问器仍然是私有的。

我要编写的测试是在进行内部测试之后

public void MyTest() {
    var objPrivateClass = Substitute.For<ISomeOtherClass>();

    var obj = new MyClassToTest();
    obj.MyPrivateClass = objPrivateClass;
    obj.DoSomething();


    objPrivateClass.Received().SayHello();
}

是否有更好的方法来进行测试,而无需修改原始代码以使其可测试?

这可能是在设置InternalsVisibleToAttribute并将属性设置为内部,这是正确的做法,但是几个小时前,我不知道InternalsVisibleToAttribute的存在,所以最好问一下:)

1 个答案:

答案 0 :(得分:3)

要回答确切的问题,您可以使用反射来达到私有成员的身份,但这是一个脆弱且缓慢的解决方案。

我能给您的最好建议是,私人物品应保持私人状态;通过其公共接口测试对象的行为。因此,如果太大且难以测试,只需将其重构为可测试的即可。想想单一责任原则控制反转原则。

编辑1 .:您可能正在寻找依赖注入的概念。在大多数情况下,这应该没问题;但是,当我们谈论高度可重用的库(您提到要制造一个库)时,其他解决方案可能更适合您的库用户(例如,创建Facade或重新考虑您的设计)。