如何测试从其他类方法内部获取值的方法



我尝试了几种方法来模拟和监视值,并在每次出现nullPointerException或其他Mockito错误时调用下面的方法。由于我是Mockito和android本身的新手,请让我知道如何为下面的方法编写AndroidTest案例,该方法也使用改装API调用。我正在尝试编写涵盖整个方法的代码。提前感谢

public  LiveData<BaseModel<Onboarding>> updateUser(Result item) {
final MutableLiveData<BaseModel<Onboarding>> data = new MutableLiveData<>();
final BaseModel<Onboarding> dataWrapper = new BaseModel<>();
Map<String, String> headers = WaApplication.getContext().getRequestHeaders();
String tenantId = WaApplication.getContext().getTenantId();

service.updateUser(tenantId,headers, item).enqueue(new Callback<UserOnboarding>() {
@Override
public void onResponse(Call<Onboarding> call, Response<Onboarding> response) {
dataWrapper.setData(response.body());
dataWrapper.setResponseCode(response.code());
data.setValue(dataWrapper);
LogUtils.d(TAG, "updateUser:HTTPS_ONBOARDING_API_ENDPOINT: "+ BuildConfig.HTTPS_ONBOARDING_API_ENDPOINT);
LogUtils.d("OnBoardingService onRes", new Gson().toJson(response.body()));
}

@Override
public void onFailure(Call<Onboarding> call, Throwable t) {
LogUtils.e(TAG, "OnBoardingService API Failed. Error - " + t.getMessage());
data.setValue(null);
}
});
return data;
}

TL;DR:

@Rule 
public InstantTaskExecutorRule InstantTaskExecutorRule = new InstantTaskExecutorRule();

我假设您想要编写一个单元测试(在JVM上运行(,而不是一个Instrumentation测试(在Android设备上运行(

在单元测试中,您对data.setValue((的调用将导致:

java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.
at android.os.Looper.getMainLooper(Looper.java)

为了能够在JVM上的单元测试中使用Android类,android.jar被添加到类路径中。这个jar包含所有的Android类,但没有实现它们。因此,如果你执行它的任何代码,它总是抛出上面的异常。Android方法调用的真正实现仅在Android设备上可用。

因此,一般来说,对于单元测试,您必须使用例如Mockito来模拟方法调用。

或者,您可以将测试作为Instrumentation测试执行(将其放入androidTest源代码集中(。然后在安卓设备上执行。

不过,在LiveData的情况下,您可以通过更改LiveData的调度方式来避免这种情况。Google为这种情况提供了一个JUnit测试规则,您必须将一个工件添加到build.gradle,并将TestRule添加到测试类

build.gradle:

testImplementation 'androidx.arch.core:core-testing:2.1.0'

测试等级:

@Rule 
public InstantTaskExecutorRule InstantTaskExecutorRule = new InstantTaskExecutorRule();

附带说明:

  • 不要在单元测试中对真实的URL进行网络或Retrofit调用。最好将baseUrl指向模拟服务器,并使用例如OkHttp MockWebServer伪造网络响应
  • 如果你的ViewModel中没有updateUser方法,你想把它放在那里。因为这正是ViewModel的用例
  • 如果在ViewModel中有updateUser方法,则不需要返回LiveDatadataLiveData应该是ViewModel的实例变量,然后您可以在ActivityFragment中观察到它
  • 你可能想使用android事实上的日志标准Timber,而不是自定义的LogUtils

相关内容

  • 没有找到相关文章

最新更新