android - 使用 Mockito 进行 Retrofit 2 api 调用的单元测试

标签 android unit-testing mockito retrofit2

我需要一些关于如何模拟 rest api 的建议。我的应用程序采用 MVP 架构。

我的 API 接口(interface):

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

还有另一种方法可以通过编写 Mock 服务来测试我的演示者。但我不太喜欢那样,我认为 Mockito 可以提供帮助。

这是我的测试类:

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()。

当然我现在的测试是行不通的。我需要一些关于如何模拟这个的建议?任何想法?谢谢。

最佳答案

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

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

关于android - 使用 Mockito 进行 Retrofit 2 api 调用的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37337477/

相关文章:

java - 我是否发现了 java.util.Calendar 错误?

visual-studio-2008 - 在 Visual Studio 2008 VC++ 中进行单元测试的程序(.exe 文件)

java - Mockito 在 createCriteria 中测试 DAO 得到 NullPointerException

android - 将折叠工具栏标题更改为微调器

android - ScrollView 没有向下滚动

java - 从 SVG 绘制图形(图像)

android - findFragmentByTag 的单元测试条件

java - 如何在 Mockito 和 JUnit 中模拟具有复杂请求的服务?

java - Mockito 和 Dexmaker 的 UnsupportedOperationException

java - 是否可以更改 Android 应用程序内的按键布局?