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

Unit testing 在复合材料上测试交互时,如何避免重复的单元测试?,unit-testing,refactoring,Unit Testing,Refactoring,想象一个过滤器系统(可能是音频过滤器或文本流过滤器) Filter基类有一个do\u Filter()方法,它接受一些输入,修改它(可能),并将其作为输出返回 存在几个使用TDD构建的子类,每个子类都有一组单独测试它们的测试 随之而来的是一个不相关类型的组合类小部件,它有两个不同过滤器类型的成员(a和b),处理完全不同的输入-也就是说,某些将由过滤器a修改的输入会在未经过滤器b修改的情况下通过,反之亦然。它的process\u data()方法调用每个筛选器成员的do\u filter() 在开

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

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

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

随之而来的是一个不相关类型的组合类
小部件
,它有两个不同
过滤器
类型的成员(
a
b
),处理完全不同的输入-也就是说,某些将由过滤器
a
修改的输入会在未经过滤器
b
修改的情况下通过,反之亦然。它的
process\u data()
方法调用每个筛选器成员的
do\u filter()

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

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


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

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

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

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


我在这里询问了关于抽象基类和单元测试的类似问题,它有一些有趣的地方,您可能会发现它们很有用


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

public void TestForFooBehaviour(IFilter filter) 
{
    /* whatever you would normally have in a test method */
}
然后从简单过滤器的原始测试和复合过滤器调用此方法。这也适用于抽象基类。显然,FooBehavior应该是您正在测试的过滤器方面的有意义的描述。对要测试的每个行为都执行此操作


如果您的语言支持duck类型或泛型,请在有帮助的情况下随意使用。

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

public void TestForFooBehaviour(IFilter filter) 
{
    /* whatever you would normally have in a test method */
}
然后从简单过滤器的原始测试和复合过滤器调用此方法。这也适用于抽象基类。显然,FooBehavior应该是您正在测试的过滤器方面的有意义的描述。对要测试的每个行为都执行此操作

如果您的语言支持duck类型或泛型,请在有帮助的情况下使用它