unit testing的改装2 api呼叫与Mockito

我需要一些关于如何嘲笑restapi的build议。 我的应用程序是在MVP架构。

我的API接口:

public interface MyAPI { @GET("{cmd}/{userName}/{password}") Observable<Response> login( @Path("cmd") String cmd, @Path("userName") String userName, @Path("password") String password ); 

我的服务:

 public class MyService implements IService { private static MyService mInstance = new MyService(); private MyAPI mApi; public static MyService getInstance() { return mInstance; } private MyService() { OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); httpClientBuilder.connectTimeout(Config.DEFAULT_TIMEOUT, TimeUnit.SECONDS); Retrofit retrofit = new Retrofit.Builder() .baseUrl(Config.kBaseUrl) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(httpClientBuilder.build()) .build(); this.mApi = retrofit.create(MyAPI.class); } public void login( Subscriber<Response> subscriber, String userName, String password) { mApi.login(Config.kLoginCmd,userName,password) .subscribeOn(Schedulers.io()) .unsubscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(subscriber); } 

我的主持人class:

 public class LoginPresenter implements LoginContract.Presenter { LoginContract.View mView; IService mService; ISession mSession; public LoginPresenter(LoginContract.View loginView, IService service, ISession session) { mView = loginView; mService = service; mSession = session; } @Override public void login(String email, String password) { Subscriber<Response> subscriber = new Subscriber<Response>() { @Override public void onCompleted() { mView.showLoading(false); } @Override public void onError(Throwable e) { mView.showError(e.getLocalizedMessage()); } @Override public void onNext(Response response) { if (response.getResults().getStatus().equalsIgnoreCase(Config.kResultCodeOK)) { mView.loginSuccess(); } else { mView.showError(response.getResults().getStatus().getErrmsg()); } } }; mView.showLoading(true); mService.login( subscriber, email, password); } 

还有另一种方法来通过编写模拟服务来testing演示者。 但我不喜欢这么多,我认为Mockito可以提供帮助。

这是我的testing课:

 public class LoginPresenterMockTest { private LoginPresenter mLoginPresenter; @Mock LoginContract.View view; @Mock IService service; @Mock ISession session; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); mLoginPresenter = new LoginPresenter(view, service, session); } @Test public void testLoginWithCorrectUserNameAndPassword() throws Exception { mLoginPresenter.login("user@email.com","password"); verify(view).loginSuccess(); } } 

我想要做的是当响应正确时,模拟响应数据调用loginSuccess()。

当然,我目前的testing是行不通的。 我需要一些build议如何嘲笑这个? 任何想法? 谢谢。

Solutions Collecting From Web of "unit testing的改装2 api呼叫与Mockito"

你可以用下面的方法来做:

 @Test public void testLoginWithCorrectUserNameAndPassword() throws Exception { // create or mock response object when(service.login(anyString(), anyString(), anyString).thenReturn(Observable.just(response)); mLoginPresenter.login("user@email.com","password"); verify(view).loginSuccess(); } @Test public void testLoginWithIncorrectUserNameAndPassword() throws Exception { // create or mock response object when(service.login(anyString(), anyString(), anyString).thenReturn(Observable.<Response>error(new IOException())); mLoginPresenter.login("user@email.com","password"); verify(view).showError(anyString); } 

感谢@Ilya Tretyakov ,我出来了这个解决scheme:

 private ArgumentCaptor<Subscriber<Response>> subscriberArgumentCaptor; @Test public void testLoginWithCorrectUserNameAndPassword() throws Exception { mLoginPresenter.login("user@email.com","password"); // create the mock Response object Response response = ...... verify(service, times(1)).login( subscriberArgumentCaptor.capture(), stringUserNameCaptor.capture(), stringPasswordCaptor.capture() ); subscriberArgumentCaptor.getValue().onNext(response); verify(view).loginSuccess(); }