C#:在密封类中模拟和测试受保护(或私有)方法 - 方法

时间:2011-01-20 14:30:16

标签: c# unit-testing protected sealed

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

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

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

  1. 让课程开启。 然后在我们的测试代码中创建从类派生的代理或适配器,以便对受保护方法进行隧道访问。
  2. 将受保护方法中的行为分解为委托/仿函数,然后重新注入。 然后独立测试分解行为。
  3. 通过调用使用受保护方法的继承层次结构中最近的公共方法进行测试。 潜在地导致大量的嘲弄,并且当测试以外的代码发生变化时会面临风险 - 创建脆弱的测试。
  4. 使用反射来访问受保护的方法。 然后直接调用它。
  5. 还有吗?

5 个答案:

答案 0 :(得分:7)

密封类中的protected方法实际上与private相同(我猜如果你密封了基类有protected成员的派生类,这些可以自然地出现。)

测试private方法毫无意义。因为除了可以通过定义类的public方法访问的行为之外,它们没有public行为,所以应该通过测试public方法来测试它们的行为。

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

我通常会选择第二种选择,假设您能够轻松地进行更改。鉴于如果你无法通过它的公共接口测试受保护/私有方法正在做什么,它可能不符合单一责任原则,并且代码可能会被分成两个类并使用组合代替。

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

double value = 0;
var fakeFilterSetHelper = Mock.Create<FilterSetHelper>(Behavior.CallOriginal);
Mock.NonPublic.Arrange<double>(fakeFilterSetHelper, memberName: "GetPriceRangeFromSession").Returns(value);