Java 如何使用Mockito模拟Api包装上的一系列调用
我不熟悉模拟和测试,但我似乎不知道测试这个api包装器需要做什么。我有一个类,它从Spotify api调用中获取曲目列表。我正在使用这个软件包 我模拟SpotifyApi类,以便在单元测试期间它实际上不会调用api。但是为了得到结果,我需要进行一系列调用,每个调用返回一个不同的类。我试着模仿每一个类,并用它们作为对其他类的回报,但这会导致问题。我不仅需要知道每个类的分类,而且在这个流程中,一些类是我无法模拟的最终类。 SearchTracksRequest.Builder尤其是最后一个类,因此模拟失败 我觉得我在这方面采取了错误的方法,因为这看起来很简单,很普通,但我不知道如何让它可测试。我是否以正确的方式进行这项工作?我应该如何为此编写测试 下面是我要测试的代码 班级Java 如何使用Mockito模拟Api包装上的一系列调用,java,junit,mockito,Java,Junit,Mockito,我不熟悉模拟和测试,但我似乎不知道测试这个api包装器需要做什么。我有一个类,它从Spotify api调用中获取曲目列表。我正在使用这个软件包 我模拟SpotifyApi类,以便在单元测试期间它实际上不会调用api。但是为了得到结果,我需要进行一系列调用,每个调用返回一个不同的类。我试着模仿每一个类,并用它们作为对其他类的回报,但这会导致问题。我不仅需要知道每个类的分类,而且在这个流程中,一些类是我无法模拟的最终类。 SearchTracksRequest.Builder尤其是最后一个类,因此
public class Spotify {
private SpotifyApi spotify;
public Spotify(SpotifyApi spotify) {
this.spotify = spotify;
}
public Track[] browse(String search) throws ParseException, SpotifyWebApiException, IOException {
return spotify.searchTracks(search)
.build()
.execute()
.getItems();
}
}
考试班
class SpotifyTest {
@Test
public void test_spotify_can_browse() throws ParseException, SpotifyWebApiException, IOException {
Track[] Exptracks = new Track[0];
SpotifyApi mockSpotify = mock(SpotifyApi.class);
SearchTracksRequest.Builder mockBuilder = mock(SearchTracksRequest.Builder.class);
SearchTracksRequest mockRequest = mock(SearchTracksRequest.class);
@SuppressWarnings("unchecked")
Paging<Track> mockExecute = (Paging<Track>) mock(Paging.class);
when(mockSpotify.searchTracks("Spirit Of Radio")).thenReturn(mockBuilder);
when(mockBuilder.build()).thenReturn(mockRequest);
when(mockRequest.execute()).thenReturn(mockExecute);
when(mockExecute.getItems()).thenReturn(Exptracks);
Track[] tracks = new Spotify(mockSpotify).browse("Spirit Of Radio");
assertEquals(tracks, Exptracks);
}
}
class测试{
@试验
public void test\u spotify\u can\u browse()抛出ParseException、spotifywebapieexception、IOException{
Track[]Exptracks=新曲目[0];
SpotifyApi mockSpotify=mock(SpotifyApi.class);
SearchTracksRequest.Builder mockBuilder=mock(SearchTracksRequest.Builder.class);
SearchTracksRequest mockRequest=mock(SearchTracksRequest.class);
@抑制警告(“未选中”)
Paging mockExecute=(Paging)mock(Paging.class);
当(mockSpotify.searchTracks(“无线电精神”))。然后返回(mockBuilder);
当(mockBuilder.build())。然后返回(mockRequest);
当(mockRequest.execute())。然后返回(mockExecute);
当(mockExecute.getItems())。然后返回(Exptracks);
Track[]tracks=newspotify(mockSpotify)。浏览(“收音机的精神”);
资产质量(轨道、出口轨道);
}
}
您可以将Mockito配置为mock final类,搜索“mock maker inline”。我可能会考虑使用间谍来做这些课程。例如,让builder类做它需要做的任何事情(如果可行的话),并且只存根“.build()”方法来为您提供模拟的SearchTracksRequest对象。在我看来,你可以在任何你觉得足够的地方画一条测试线。例如,仅验证在查询中调用了“.searchTracks(search)”方法就足够了。当库代码的调用链不是您的代码时,测试库代码的调用链是很困难的。我将签出模拟内联生成器,但我看得越多,唯一需要以不同方式工作的方法是.execute()
,因为我不想要API调用。有没有办法让它切换SearchTracksRequest.execute()方法和一个自定义返回,但其他所有内容保持不变?是的,使用spy而不是mock,spy将对象保留为,并使您能够存根它的一些行为。看看这个库的Github,看看它们是如何编写测试的。看起来他们设置了一个模拟SpotifyApi对象,并在整个测试过程中使用它,您可能希望执行类似的操作。