如何使用 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。
我想测试 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。