简体   繁体   中英

Mockito test - reason of failing my testcase

Learnt JUnit yesterday, learning Mockito today

I wrote a simple class;

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;
    }
}

And trying to test it as follows

@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());
}

Output:

amit

true

false

As I set seekHeader() to return true. Why fo.autoMove() is returning false?

With a mock, none of the methods actually do anything, unless you explicitly specify that they should. The whole point of a mock is that the functionality has been replaced, either by no functionality at all (the default), or by functionality that you stub.

The default functionality for a mock is that every method does nothing at all, then returns either false (for booleans), zero (for numeric primitives), an empty collection, or null . So in this case, autoMove will always return false , unless you stub it to do something different.

The whole idea of using mocks is that you don't mock the class that you're trying to test . Instead, you mock other classes that it interacts with. So if a method of class A calls a method of class B , and you wish to test class A ; then you would use a mock of class B , and stub the method of B that gets called.

You can do it using spy as follows;

@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());
    }

Why your code is failing

Because you were not stubbing fo.autoMove() . When you call a real method with mocked object, actual method never runs. It just returns default value of return-type or stubbed value. So even if you return true from autoMove() , it will return false for a mock object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM