我应该在单元测试中访问受保护的方法吗?

3

关于我之前提出的这个问题,现在我又遇到了一个单元测试方面的问题。

我的当前问题是如何测试抽象类Component中的protected方法。

我已经成功地实现了一个名为ConcreteComponent的模拟类,它很好地继承了抽象类的所有内容。

但问题在于,我将这个具体类放在了我的单元测试文件中。测试protected方法的唯一方法是创建一个私有访问器,然而,我不能在同一文件中创建私有访问器,因此无法访问这些受保护的方法。

我试图将模拟的具体类放在一个不同的命名空间下的单独文件中,这样可以创建一个私有访问器,使单元测试文件可以使用它。这个方法很有效,但后来我发现我需要将这个模拟的具体类放在与单元测试文件相同的文件中。

因此,我现在有以下两个问题:

1)有哪些可能的解决方法可以解决这个问题?

2)为什么我不能为一个与单元测试类在同一文件和命名空间下的模拟类创建私有访问器?


“为什么你不能”是一个很好的问题。为什么你不能呢?到底发生了什么或者阻止了你呢? - JRoughan
好吧,无论出于什么原因,VS2008都不允许我这样做。当类与单元测试在同一个文件中时,右键单击模拟类名称时没有创建私有访问器的选项。但是,当我将模拟类放在单独的文件中时,创建私有访问器的选项就会出现。 - Anthony
啊,原来是IDE不让你这样做。我没意识到你在使用MSTEST和自动生成的访问器。既然如此,我会遵循下面Saurabh的建议,相信/确保公共接口正在使用受保护的代码,或者如果没有使用,则为什么要在意它是否损坏了? - JRoughan
2个回答

2
您可以查看PrivateObject类来访问您的测试中类的非公共API。它在内部使用反射。类的受保护资源仍然是外部客户端(在这种情况下是子类或派生类)的API。因此,希望测试此类API是可以理解的。出于测试受保护的API的目的,我不建议污染一个类以公开API。但是,由于在您的情况下派生类在测试项目中,您实际上可以提供公共API,以使测试更容易并提高性能(反射将更慢,如果您正在运行测试,则根据测试数量等会使测试运行变慢)。

尽管排名最高的答案很好,但我很惊讶为什么没有给PrivateObject类点赞!+1。 - Arj
先生,您刚刚改变了我的人生! - Dean Martin

0

保护功能存在的原因是您不希望将其暴露给客户端。但是,如果它受到保护,则可以通过公共接口通过某些满足条件来访问它,如果没有,则是死代码,因此请将其删除。

所以黄金法则是

1- 不要尝试使用技术(反射等)规避测试私有/受保护方法,而是通过公共接口进行单元测试私有/受保护,并且顺便问一下,为什么您使用VS 2008测试而不是NUnit呢?


1
我会建议将这个功能重构到其他类中,这样它就可以单独进行单元测试。 - Ralph Willgoss
同意;私有方法应该通过公共接口间接测试,或者它们足够复杂,应该被提取到一个新类中。 - Robert Johnson
即使受保护的方法被继承,但不能直接被继承类的使用者使用,必须通过您发布的公共接口访问,因此必须仅通过该接口进行测试。 - TalentTuner
1
@Saurabh:那么,如果你是一个框架开发者,并且在你的框架中没有任何继承类,你如何测试你的代码呢?你的框架的客户端应该从你的类派生并使用你的受保护的API,而你仍然希望这个受保护的API能够正常工作并进行单元测试,对吧? - Mehmet Aras
但是我确实有一个继承自抽象类的类,其中包含受保护的方法。那么我应该真正做什么样的解决方案呢?以防万一,我在上面的问题中提出的观点不够清晰,我的抽象类名为“Component”,其中包含受保护的方法。我创建了一个模拟类“ConcreteComponent”,它继承自抽象类。 - Anthony
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接