我将Junit与Mockito结合使用。我使用了mockito的验证方法+ junit断言来完成验证。这不可取吗?我们应该使用其中一种而不是两种吗?
答案 0 :(得分:3)
使用两者都没有错。
Mockito的verify
用于声明在给定模拟上使用期望值调用expect方法。
JUnit' s assertXYZ
用于断言某些结果是期望的结果。
两者都是有效的验证,如果两者都相关,则应使用两者。
例如,考虑以下(当然是人为的)情况:
您有一个执行某些数学计算的界面:
public interface ValueProducer {
public int getValue(int val);
}
一个班级将其产生的任何结果加倍:
public class Doubler {
public static int doubleThatResult (ValueProducer producer, int val) {
return 2 * producer.getValue(val);
}
}
测试它需要断言两件事:
getValue
被恰当地称为所以,例如:
public class DoublerTest {
@Test
public void testDoubleThatResult() throws Exception {
int value = 7; // Or any other value
int returnMock = 13; // Or any other value
ValueProducer producerMock = mock(ValueProducer.class);
when(producerMock.getValue(value)).thenReturn(returnMock);
int actual = Doubler.doubleThatResult(producerMock, value);
verify(producerMock);
assertEquals(26, actual);
}
}
答案 1 :(得分:1)
Mureinik的回答是绝对正确的 - 断言和验证是互补的,并且可以很好地协同工作 - 但是对于单一行为同时做两件事可能是多余的。
目标通常是以最灵活和与实现无关的方式表达测试。在这种意义上,状态测试(带断言)通常是最合适的选择:只要结果状态正确,调用哪些方法并不重要。尽管可能,Mockito验证可能会引入脆弱性(代码行为正确但测试被破坏)。 Mockito本身在verify(T)
's Javadoc和the linked article by Mockito's creator Szczepan Faber中警告过这一点。
这种冗余肯定不是最糟糕的事情:它确实测试了系统的属性,并且在测试与敏感,遗留,第三方或经常变化的依赖关系的交互时可能是值得的。但是,如果相互作用不重要,那么这些额外的验证可能会以脆弱为代价。
其他时候,确认正确的行为意味着测试副作用 - 例如,确保调用someSystem.reset()
,或通过验证提供程序未调用来测试缓存。这些是验证的完美示例,因为与外部服务的交互是关键的可测试行为。在某些情况下,Mockito验证是唯一方式来做出正确的断言。
许多测试用例是上述的组合,因此可以随意使用断言和验证;请记住,状态测试通常是充分的,也是首选。