Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用Mockito模拟Api包装上的一系列调用_Java_Junit_Mockito - Fatal编程技术网

Java 如何使用Mockito模拟Api包装上的一系列调用

Java 如何使用Mockito模拟Api包装上的一系列调用,java,junit,mockito,Java,Junit,Mockito,我不熟悉模拟和测试,但我似乎不知道测试这个api包装器需要做什么。我有一个类,它从Spotify api调用中获取曲目列表。我正在使用这个软件包 我模拟SpotifyApi类,以便在单元测试期间它实际上不会调用api。但是为了得到结果,我需要进行一系列调用,每个调用返回一个不同的类。我试着模仿每一个类,并用它们作为对其他类的回报,但这会导致问题。我不仅需要知道每个类的分类,而且在这个流程中,一些类是我无法模拟的最终类。 SearchTracksRequest.Builder尤其是最后一个类,因此

我不熟悉模拟和测试,但我似乎不知道测试这个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对象,并在整个测试过程中使用它,您可能希望执行类似的操作。