是的,但并不总是孤立的
请允许我详细说明:
什么是单元测试?
来自有效地使用遗留代码1:
单元测试一词在软件开发中有着悠久的历史。普遍于
大多数单元测试的概念是认为它们是独立于个体的测试
软件的组成部分。什么是组件?定义不同,
但在单元测试中,我们通常关注系统中最原子的行为单元。在过程代码中,单元通常是函数。在面向对象的代码中,单位是类。
请注意,对于 OOP,您可以在其中找到 getter 和 setter,单位是 类,不一定是单个方法。
什么是好的测试?
所有需求和测试都遵循Hoare logic的形式:
{P} C {Q}
地点:
-
{P} 是前提条件(给定)
-
C是触发条件(when)
-
{Q} 是后置条件 (then)
然后是格言:
测试行为,而不是实现
这意味着你不应该测试C如何实现后置条件,你应该检查{Q}是C的结果。
对于 OOP,C 是一个类。所以你不应该测试内部效应,只测试外部效应。
为什么不单独测试 bean getter 和 setter
Getter 和 setter 可能涉及一些逻辑,但只要该逻辑没有外部影响 - 使它们成为 bean 访问器2)测试将不得不查看内部对象,因此不仅违反封装,而且还测试实现。
因此,您不应该孤立地测试 bean getter 和 setter。这很糟糕:
Describe 'LineItem class'
Describe 'setVAT()'
it 'should store the VAT rate'
lineItem = new LineItem()
lineItem.setVAT( 0.5 )
expect( lineItem.vat ).toBe( 0.5 )
虽然如果setVAT 会抛出异常,但相应的测试将是合适的,因为现在有外部影响。
应该如何测试 getter 和 setter?
如果这样的改变对外部没有影响,那么改变一个对象的内部状态实际上是没有意义的,即使这种影响稍后会出现。
所以对 setter 和 getter 的测试应该关注这些方法的外部影响,而不是内部影响。
例如:
Describe 'LineItem class'
Describe 'getGross()'
it 'should return the net time the VAT'
lineItem = new LineItem()
lineItem.setNet( 100 )
lineItem.setVAT( 0.5 )
expect( lineItem.getGross() ).toBe( 150 )
你可能会想:
等一下,我们在这里测试getGross() 不是 setVAT()。
但如果setVAT() 发生故障,该测试应该同样失败。
1Feathers, M., 2004。有效地使用遗留代码。 Prentice Hall 专业人士。
2Martin, R.C.,2009 年。清洁代码:敏捷软件工艺手册。培生教育。