如何使用 mockito 模拟注入对象的属性

How to mock an attribute of an injected object using mockito

我想测试 deleteTracks 方法,为此我需要模拟一个播放列表,我在调用 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

}

这是我的 class 测试:

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


    }

这不起作用的原因是您没有将模拟作为参数提供给 PlaylistBusiness。

提供错误是值得的,但您正在定义其行为的模拟从未在测试中的 class 中使用。

被测实例(PlaylistBusinessBean)被DI框架注入。然而,那个是不使用在测试中创建的 PlaylistDaoBean 的模拟。 mock 只是一个局部变量,不会在任何地方使用。

与其使用 PlaylistBusinessBean 的注入实例,不如以编程方式创建一个并将 PlaylistDaoBean 模拟传递给它:

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


    }

一般说明:

  • 这是一个单元测试,所以我总是建议单独测试代码,独立于 DI 和任何注入的代码。
  • 但是,如果确实需要,通常也可以使用特定于测试的 DI 上下文,在需要时构建注入模拟到被测试的 bean。如何做到这一点取决于所使用的 DI。