编写单元测试以获得不变性

时间:2018-05-28 23:21:24

标签: java junit immutability

我写了几个被设计为不可变的类。我正试图测试它们。我当然可以使用MobilityDetector,但我想自己写一些东西。不广泛,基本的东西。

我试图在我的测试用例中提出的想法,即在每个操作上,我执行操作的对象的对象引用将与从操作返回的对象不同。

例如,假设我设计了一个类add并且它有一个名为@Test public void test_add(){ Digit zero = Digit.getInstance(); //ignore why i am using getinstance here Digit result = zero.add(new Random().nextInt()); assertNotEqual (zero, result); //there is no equal method overridden in Digit class } 的方法。所以我写的测试用例是

assertNotEqual

我的假设是zero将测试两个对象(resultzero)的引用。如果两个引用都不同,则意味着对 if (p == head && p == tail) { tail = NULL; head = NULL; delete p; break; } 对象执行的操作确实返回了一个新对象而不是旧对象。

这有意义吗?

2 个答案:

答案 0 :(得分:0)

  

我的假设是assertNotEqual将测试两个对象的引用

不要假设。阅读javadoc!它说:

  

断言两个对象不相等。如果是,则抛出没有消息的AssertionError。如果意外和实际为空,则认为它们是相等的。

换句话说,这是使用测试相等性的标准Object::equals(Object)方法。这只会使用==比较,如果这是相关的equals(Object)方法的话。

要回答您的问题,对zero == result的测试既不是对不变性的必要或充分的测试。

  • zero加一些随机整数可以为零
  • zero ====而不是resultzero的事实并不能证明Digit对象的状态没有改变。

事实上,我并不认为在一般意义上存在对不可变性的有效测试。不变性属性是关于Digit类的抽象边界内发生的事情。如果您将Digit视为真正的黑匣子,则无法假设您将能够检测到框内的更改。

测试(真实)不变性的唯一有效方法是将测试与(确定的)知识结合起来"在框内&#34 ;;即代码检查Digit类和白盒测试。

另一种选择,就是定义你的意思"不变性"就toString()的某些外部可见属性而言;例如{{1}}返回的内容。 (但这种方法也存在问题......)

答案 1 :(得分:0)

assertEquals / assertNotEquals使用对象的equals方法测试相等性。它与assertTrue(expected.equals(actual))类似。如果不覆盖equal,它将检查对象的引用(hashcode),但我不会依赖于此,因为如果最终实现equals方法,这可能会破坏您的测试。

如果要检查对象是否相同(或不是),请使用assertSame / assertNoSame测试引用相等性,类似于assertTrue(expected == actual)

但要检查不变性,不仅要检查是否有任何修改操作返回一个新实例,而且检查原始对象仍然没有改变!

执行此操作的一种方法是创建原始对象的引用对象(或克隆),并另外检查,原始对象在调用{{1}后仍然等于引用对象}}。

add

但这反过来要求你正确地实现等于。