我正在查看一个相当现代的项目,该项目非常强调单元测试。根据古老的格言“面向对象编程中的每个问题都可以通过引入新的间接层来解决”,这个项目正在运动多层间接。副作用是相当多的代码如下所示:
public bool IsOverdraft)
{
balanceProvider.IsOverdraft();
}
现在,由于强调单元测试和保持高代码覆盖率,每段代码都有针对它编写的单元测试。因此,这个小方法将存在三个单元测试。那些会检查:
- 如果 balanceProvider.IsOverdraft() 返回 true 那么 IsOverdraft 应该返回 true
- 如果 balanceProvider.IsOverdraft() 返回 false 那么 IsOverdraft 应该返回 false
- 如果 balanceProvider 抛出异常,则 IsOverdraft 应该重新抛出相同的异常
更糟糕的是,使用的模拟框架 (NMock2) 接受方法名称作为字符串文字,如下所示:
NMock2.Expect.Once.On(mockBalanceProvider)
.Method("IsOverdraft")
.Will(NMock2.Return.Value(false));
这显然使“红色,绿色,重构”规则变为“红色,绿色,重构,在测试中重命名,在测试中重命名,在测试中重命名”。使用像 Moq 这样的不同模拟框架将有助于重构,但它需要对所有现有的单元测试进行扫描。
处理这种情况的理想方法是什么?
A) 保留较小级别的层,以便不再发生这些转发呼叫。
B) 不要测试那些转发方法,因为它们不包含业务逻辑。出于覆盖目的,它们都用 ExcludeFromCodeCoverage 属性标记。
C) 仅在调用正确的方法时进行测试,而不检查返回值、异常等。
D)收拾一下,继续写那些测试;)