想象一下过滤系统(可能是音频过滤器或文本流过滤器)。
Filter
基类有一个do_filter()
方法,它接受一些输入,修改它(可能),并将其作为输出返回。
存在几个使用TDD构建的子类,每个子类都有一组测试,可以单独测试它们。
一个复合类,一个不相关的类型Widget
,它有两个不同Filter
类型的成员(a
和b
),处理完全不同输入 - 也就是说,由过滤器a
修改的某些输入通过过滤器b
未经修改而传递,反之亦然。其process_data()
方法会调用每个过滤器成员的do_filter()
。
在开发复合类时,会出现一些测试,检查Widget
的过滤器不同时处理相同数据的假设。
问题是,这些测试看起来与单个过滤器的测试完全相同。虽然可能还有其他测试,哪些测试输入应该由两个过滤器修改,但是许多测试几乎可以从每个过滤器的测试中复制和粘贴,只需要进行少量修改使用Widget
进行测试(例如调用process_data()
),但输入数据和断言检查是相同的。
这种复制闻起来很糟糕。但是想要测试组件的交互似乎是正确的。什么样的选择可以避免这种重复?
答案 0 :(得分:3)
在一个测试套件/类中有一个方法
public void TestForFooBehaviour(IFilter filter)
{
/* whatever you would normally have in a test method */
}
然后从简单过滤器的原始测试以及复合过滤器调用此方法。这也适用于抽象基类。显然,FooBehaviour应该是您正在测试的过滤器方面的有意义的描述。对要测试的每个行为执行此操作。
如果您的语言支持鸭子打字或泛型,请随时使用它。如果有帮助的话。
答案 1 :(得分:1)
我经常将测试逻辑提取到单独的类中,因此我将过滤器测试提取到一个单独的类中,该类本身不是单元测试。特别是如果您的测试类与生产代码在物理上是分开的,这实际上是解决此问题的一种不错的方法(即,没有人会认为它是生产代码,因为它在测试空间中)
答案 2 :(得分:1)
我在这里询问了一些关于抽象基类和单元测试的类似内容,它有一些你可能会觉得有用的有趣点。