使用junit断言和mockito验证

时间:2015-04-27 22:03:22

标签: java junit mockito

我将Junit与Mockito结合使用。我使用了mockito的验证方法+ junit断言来完成验证。这不可取吗?我们应该使用其中一种而不是两种吗?

2 个答案:

答案 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);
    }
}

测试它需要断言两件事:

  1. getValue被恰当地称为
  2. 结果加倍
  3. 所以,例如:

    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 Javadocthe linked article by Mockito's creator Szczepan Faber中警告过这一点。

这种冗余肯定不是最糟糕的事情:它确实测试了系统的属性,并且在测试与敏感,遗留,第三方或经常变化的依赖关系的交互时可能是值得的。但是,如果相互作用不重要,那么这些额外的验证可能会以脆弱为代价。

其他时候,确认正确的行为意味着测试副作用 - 例如,确保调用someSystem.reset(),或通过验证提供程序未调用来测试缓存。这些是验证的完美示例,因为与外部服务的交互是关键的可测试行为。在某些情况下,Mockito验证是唯一方式来做出正确的断言。

许多测试用例是上述的组合,因此可以随意使用断言和验证;请记住,状态测试通常是充分的,也是首选。