5

我有一个带有受保护方法的密封类,我想测试其行为。这使得很难直接测试,也很难模拟。

它位于不是以 TDD 方式开发的代码库中,我现在正在为特定功能添加单元测试。

在这种情况下,可能的一般方法是什么?目前我有:

  1. 让班级解封。然后在我们的测试代码中创建一个派生自该类的代理或适配器,以隧道访问受保护的方法。
  2. 将受保护方法中的行为分解为委托/函子,然后重新注入它。然后独立测试分解后的行为。
  3. 通过调用继承层次结构中使用受保护方法的最接近的公共方法进行测试。当被测代码以外的代码发生变化时,可能会导致大量的嘲笑和暴露风险——创建脆弱的测试。
  4. 使用反射来访问受保护的方法。然后直接调用。

还有吗?

4

5 回答 5

8

密封类中的protected方法实际上是相同的private(我猜如果你密封一个派生类,其中基类有一个protected成员,这些自然会出现。)

而且没有任何意义的测试private方法。public因为除了可以通过定义类的方法访问之外,它们没有其他行为,因此public应该通过测试public方法来测试它们的行为。

于 2011-01-20T14:41:41.533 回答
3

Microsoft Moles帮助使用非虚拟方法模拟未密封的类。它不能模拟私有方法,但这是多余的,因为您可以模拟在特定类之外使用的更高级别的公共方法,并且您可以模拟模拟一个公共方法的所有必要行为。

为什么你应该测试私有/受保护的方法?您可以使用内部方法和InternalVisibleToAttribute来实现这一点。但一般来说,您应该只测试公共行为(即只测试公共接口)。

于 2011-01-20T14:50:34.537 回答
2

假设您有能力使更改相当容易,我通常会选择第二种选择。鉴于如果您无法通过其公共接口测试受保护/私有方法正在做什么,那么它可能无论如何都不符合单一责任原则,并且代码可能会被分成两个类并使用组合来代替。

于 2011-01-20T14:44:29.937 回答
1

您可以使用一些框架进行模拟 - 例如JustMock(由 Telerik 提供)支持密封私有方法的模拟......不幸的是,我认为 JustMock 的这一部分是付费的,但至少您可以尝试试用版。

于 2011-01-20T14:38:54.253 回答
1

您可以使用 JustMock 框架。例如:

double value = 0;
var fakeFilterSetHelper = Mock.Create<FilterSetHelper>(Behavior.CallOriginal);
Mock.NonPublic.Arrange<double>(fakeFilterSetHelper, memberName: "GetPriceRangeFromSession").Returns(value);
于 2016-09-13T16:33:21.623 回答