在测试复合材料上的交互时,如何避免重复单元测试?

时间:2009-02-14 14:06:45

标签: unit-testing refactoring

想象一下过滤系统(可能是音频过滤器或文本流过滤器)。

Filter基类有一个do_filter()方法,它接受一些输入,修改它(可能),并将其作为输出返回。

存在几个使用TDD构建的子类,每个子类都有一组测试,可以单独测试它们。

一个复合类,一个不相关的类型Widget,它有两个不同Filter类型的成员(ab),处理完全不同输入 - 也就是说,由过滤器a修改的某些输入通过过滤器b未经修改而传递,反之亦然。其process_data()方法会调用每个过滤器成员的do_filter()

在开发复合类时,会出现一些测试,检查Widget的过滤器不同时处理相同数据的假设。

问题是,这些测试看起来与单个过滤器的测试完全相同。虽然可能还有其他测试,哪些测试输入应该由两个过滤器修改,但是许多测试几乎可以从每个过滤器的测试中复制和粘贴,只需要进行少量修改使用Widget进行测试(例如调用process_data()),但输入数据和断言检查是相同的。

这种复制闻起来很糟糕。但是想要测试组件的交互似乎是正确的。什么样的选择可以避免这种重复?

3 个答案:

答案 0 :(得分:3)

在一个测试套件/类中有一个方法

public void TestForFooBehaviour(IFilter filter) 
{
    /* whatever you would normally have in a test method */
}

然后从简单过滤器的原始测试以及复合过滤器调用此方法。这也适用于抽象基类。显然,FooBehaviour应该是您正在测试的过滤器方面的有意义的描述。对要测试的每个行为执行此操作。

如果您的语言支持鸭子打字或泛型,请随时使用它。如果有帮助的话。

答案 1 :(得分:1)

我经常将测试逻辑提取到单独的类中,因此我将过滤器测试提取到一个单独的类中,该类本身不是单元测试。特别是如果您的测试类与生产代码在物理上是分开的,这实际上是解决此问题的一种不错的方法(即,没有人会认为它是生产代码,因为它在测试空间中)

答案 2 :(得分:1)

我在这里询问了一些关于抽象基类和单元测试的类似内容,它有一些你可能会觉得有用的有趣点。

How to unit test abstract classes: extend with stubs?