使用Mockito测试块是否正确

时间:2016-10-16 22:04:02

标签: java unit-testing testing mockito verify

我有一个void函数,它不返回任何带有if块的东西。单元测试是否有办法验证" if"块被触动了吗?

例如,测试" if"在以下功能中:

public void doSomething(){
    if(someCondition){
        int foo = doThis();
    }
    // ---- 
    // remaining code
} 

private int doThis(){
    return 100;
}

2 个答案:

答案 0 :(得分:1)

在执行UnitTest时,您希望测试可观察行为,而不是代码

可观察行为是:

  • 返回(公共)接口方法的值
  • 与其他对象(依赖关系)的交互
  • 对象状态的变化(通常是吸气剂结果的变化)

这些是通过被测试类(CUT)的公共接口进行测试的。这些公共接口并不意味着公共方法,而是指使用CUT预期由代码调用的方法。

<小时/> 在您的情况下,您希望在调用方法时测试对象的状态更改作为副作用。

但问题是您的代码不会更改对象状态,因此无法测试任何内容。

从技术上讲,您可以提高getter方法的可见性并使用Mockito进行模拟,但这与整个代码一样无用。

<强>修订
我写这个是因为OP有一个分配来做。我想强调,这应该是的方式。

<小时/> 由于要观察的方法是私有的,因此您有两个选择:

  1. 使观察的方法对测试类可见。 然后你可以使用常规的Mockito功能:

    /*ClassUnderTest CUT */ 
    public void doSomething(){
    if(someCondition){
        int foo = doThis();
    }
    // ---- 
    // remaining code
    } 
    
    /* package private, test class should be in same package  */ 
    int doThis(){
        return 100;
    }
    
    /* TestClass */
    @Test
    public void doSomething__conditionTrue__callesMemberMethod(){
       ClassUnderTest cut = Mockito.spy(new ClassUnderTest());
       // anything needed to make the condition true
    
       cut.doSomething();
    
       Mockito.verify(cut).doThis();
    }
    
    @Test
    public void doSomething__conditionFalse__doesNotCallMemberMethod(){
       ClassUnderTest cut = Mockito.spy(new ClassUnderTest());
       // anything needed to make the condition false
    
       cut.doSomething();
    
       Mockito.verify(cut,never()).doThis();
    }
  2. 使用PowerMock(-ito)
    但PowerMockito更改了CUT的字节代码,因此您无法真正测试您的CUT。我强烈建议您不要使用它,除非您必须测试其他不可测试的遗留代码。

答案 1 :(得分:1)

如果你的方法返回void,那意味着它可能做的唯一工作就是产生副作用。那就是你REALY要测试的东西。

  1. 您设置了外部状态
  2. 您运行测试中的方法
  3. 您检查状态是否已更改,因为您希望它发生变化。
  4. 为测试中的方法内的每个执行路径准备外部状态,这将涵盖代码的所有可能结果。