Mockito测试 - 我的测试用例失败的原因

时间:2012-09-25 01:57:44

标签: java junit4 mockito

昨天学会了JUnit,今天学习Mockito

我写了一个简单的类;

public class FileOperations {
    public boolean autoMove(){
        List<byte[]> patterns = getListofPatterns();
        for(byte[] pattern: patterns){
            System.out.println(new String(pattern));
            if(seekInHeader(pattern)){
                //logic to move file of specific folder of specific extension
                return true;
            }
        }
        return false;
    }

    public boolean seekInHeader(byte[] pattern){
        return false;
    }

    public List<byte[]> getListofPatterns(){
        return null;
    }
}

尝试按如下方式测试

@Test
public void autoMoveTest(){
    FileOperations fo = mock(FileOperations.class);//stub
    List<byte[]> dummyPatterns = new ArrayList<byte[]>();//specify stub value
    dummyPatterns.add("amit".getBytes());

    when(fo.getListofPatterns()).thenReturn(dummyPatterns);
    when(fo.seekInHeader(anyString().getBytes())).thenReturn(true);

    System.out.println(new String(fo.getListofPatterns().get(0)));
    System.out.println(fo.seekInHeader("amit".getBytes()));
    System.out.println(fo.autoMove());
    assertTrue(fo.autoMove());
}

输出:

  

阿米特

     

是真的

     

我设置seekHeader()返回true。为什么fo.autoMove()返回false?

2 个答案:

答案 0 :(得分:3)

使用模拟,没有任何方法实际上做任何事情,除非你明确指定它们应该。模拟的重点在于功能已被替换,无论是完全没有功能(默认),还是由存根功能替换。

模拟的默认功能是每个方法完全没有,然后返回false(对于布尔值),零(对于数字基元) ),空集合,或null。因此,在这种情况下,autoMove将始终返回false,除非您将其存根以执行其他操作。

使用模拟的整个想法是, 不要模拟 您正在尝试测试的类 < / strong>即可。相反,您可以模拟与其交互的其他类。因此,如果类A的方法调用类B的方法,并且您希望测试类A;那么你将使用类B的模拟,并存根被调用的B方法。

答案 1 :(得分:1)

您可以使用spy执行以下操作;

@Test
    public void autoMoveTest(){
        FileOperations fo = new  FileOperations("");
        FileOperations spyFo = spy(fo);

        List<byte[]> dummyPatterns = new ArrayList<byte[]>();//specify stub value
        dummyPatterns.add("amit".getBytes());

        when(spyFo.getListofPatterns()).thenReturn(dummyPatterns);
        when(spyFo.seekInHeader(anyString().getBytes())).thenReturn(true);//stubbing a method

        assertTrue(spyFo.autoMove());
    }

为什么您的代码失败

因为你没有追踪fo.autoMove()。当您使用模拟对象调用实际方法时,实际方法永远不会运行。它只返回return-type或stubbed值的默认值。因此,即使您从true返回autoMove(),它也会为模拟对象返回false。