0

昨天学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?

4

2 回答 2

3

使用模拟,任何方法实际上都不会做任何事情,除非您明确指定它们应该这样做。模拟的全部意义在于功能已被替换,要么完全没有功能(默认),要么被您存根的功能所替换。

模拟的默认功能是每个方法什么都不做,然后返回false(对于布尔值)、零(对于数字基元)、空集合或null. 所以在这种情况下,autoMove总是会返回false,除非你把它存根做一些不同的事情。

使用模拟的整个想法是你不要模拟你试图测试的类。相反,您模拟了与之交互的其他类。因此,如果一个类A的方法调用了一个类的方法B,并且您希望测试类A;然后你会使用一个模拟类B,并存根B被调用的方法。

于 2012-09-25T04:43:30.013 回答
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()。当您使用模拟对象调用真实方法时,实际方法永远不会运行。它只返回返回类型的默认值或存根值。因此,即使您true从中返回autoMove(),它也会为模拟对象返回 false。

于 2012-09-27T01:19:38.620 回答