Search code examples
javamockitotestngguice

How to mock an attribute of an injected object using mockito


I would like to test the method deleteTracks and for this I need to mock a Playlist that I retrive after calling playlistDaoBean.getPlaylistByUUID(uuid)

public class PlaylistBusines {

private PlaylistDao playlistDao;

@Inject
public PlaylistBusinessBean(PlaylistDaoBean playlistDaoBean){
    this.playlistDaoBean = playlistDaoBean;
}

List<PlayListTrack> deleteTracks(String uuid, List<Integer> indexes) throws PlaylistException {


    PlayList playList = playlistDaoBean.getPlaylistByUUID(uuid);
    // TODO

}

This is my class test:

public class PlaylistBusinessTest {

    @Inject
    PlaylistBusinessBean playlistBusinessBean;


     @Test
    public void testRemoveTracks() throws Exception {

    PlayList playList = new PlayList();
    playList.setId(222)
    playList.setName("fake name");


    PlaylistDaoBean playlistDaoBeanMock = mock(PlaylistDaoBean.class);
    when(playlistDaoBeanMock.getPlaylistByUUID(uuid)).thenReturn(playList);


    playlistBusinessBean.removeTracks(uuid, Arrays.asList(2, 3));


    }

Solution

  • The instance under test (PlaylistBusinessBean) is injected by a DI framework. That one, however, is of not using the mock of PlaylistDaoBean created in the test. The mock is just a local variable, and it is not used anywhere.

    Rather than that using an injected instance of PlaylistBusinessBean, create one programatically and pass the PlaylistDaoBean mock to it:

    public class PlaylistBusinessTest {
    
         @Test
        public void testRemoveTracks() throws Exception {
    
        PlayList playList = new PlayList();
        playList.setId(222)
        playList.setName("fake name");
    
    
        PlaylistDaoBean playlistDaoBeanMock = mock(PlaylistDaoBean.class);
        when(playlistDaoBeanMock.getPlaylistByUUID(uuid)).thenReturn(playList);
    
        PlaylistBusinessBean playlistBusinessBean = new PlaylistBusinessBean(playlistDaoBeanMock);
    
        playlistBusinessBean.removeTracks(uuid, Arrays.asList(2, 3));
    
    
        }
    

    General notes:

    • It's a unit test so I would always recommend to test the code in isolation, independent on DI and any injected code.
    • However, if really needed, it is usually also possible a test-specific DI context, that builds injects mocks to beans under tests where required. How to do that depends on the DI used.