2016-05-20 18 views
7

残りのAPIを模擬する方法についてのアドバイスが必要です。私のアプリケーションはMVPアーキテクチャになっています。 APIのための改造のユニットテスト2 api call with Mockito

マイインタフェース:

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

マイプレゼンタークラス:モックサービスを書き込むことによって、私のプレゼンターをテストするための別の方法があります

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

。しかし私はそんなに好きではないし、モキトが助けることができると思う。ここで

は私のテストクラスです:

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("[email protected]","password"); 
     verify(view).loginSuccess(); 
    } 

} 

私が何をしたいのか、応答が正しいとき、私は)(レスポンスデータ呼LOGINSUCCESSをモックです。

もちろん、私の現在のテストは機能しません。私はこれを模倣する方法についていくつかのアドバイスが必要ですか?何か案が?ありがとう。あなたは次の方法でそれを行うことができます

答えて

5

@Ilyaトレチャコフため

@Test 
public void testLoginWithCorrectUserNameAndPassword() throws Exception { 
    // create or mock response object 
    when(service.login(anyString(), anyString(), anyString).thenReturn(Observable.just(response)); 
    mLoginPresenter.login("[email protected]","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("[email protected]","password"); 
    verify(view).showError(anyString); 
} 
+0

'' 'Mockito.when(service.login(あなたは最初のパラメータを指定するのですか?それはサブスクライバです。私はそれを任意の()にキャストすることはできません。どのようにする必要がありますか?()、anyString()、anyString私は?ありがとう –

+0

申し訳ありませんが、私はあなたが加入者を渡すことに気付かなかった。私はそれがより良いと思うObservableを返し、プレゼンタークラスでそれを購読するサービスメソッドを探します。この場合、提供されたコードが機能します。さもなければ、mApiをモックする必要があります。 –

+0

** ArgumentCaptor **による問題の修正 –

3

おかげで、私はこのソリューションを出てきた:

private ArgumentCaptor<Subscriber<Response>> subscriberArgumentCaptor; 

@Test 
public void testLoginWithCorrectUserNameAndPassword() throws Exception { 
    mLoginPresenter.login("[email protected]","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(); 
}