Aab*_*ani 55 junit android unit-testing android-gradle-plugin retrofit
我试图为每一块代码集成单元测试用例.但是我在为通过改造进行的api调用添加测试用例时遇到了问题.
JUnit编译器从不执行CallBack函数中的代码.
还有另一个选项是将所有api调用同步用于测试目的,但对于我的应用程序中的每个案例都不可能.
我该如何解决这个问题?我必须以任何方式在api调用中添加测试用例.
mac*_*usz 26
我使用Mockito,Robolectric和Hamcrest库测试我的Retrofit回调.
首先,在模块的build.gradle中设置lib堆栈:
dependencies {
testCompile 'org.robolectric:robolectric:3.0'
testCompile "org.mockito:mockito-core:1.10.19"
androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
}
Run Code Online (Sandbox Code Playgroud)
在jour项目的全局build.gradle中,将以下行添加到buildscript依赖项:
classpath 'org.robolectric:robolectric-gradle-plugin:1.0.1'
Run Code Online (Sandbox Code Playgroud)
然后在Android Studio中输入"Build Variants"菜单(快速找到它,按Ctrl + Shift + A并搜索它),并将"Test Artifact"选项切换为"Unit Tests".Android studio会将您的测试文件夹切换为"com.your.package(test)"(而不是androidTest).
好.设置完成,时间写一些测试!
假设您已经有一些改进的api调用来检索需要放入RecyclerView等适配器的对象列表.我们想测试适配器是否在成功调用时填充了适当的项目.要做到这一点,我们需要切换你用于使用模拟调用的Retrofit接口实现,并利用Mockito ArgumentCaptor类做一些假响应.
@Config(constants = BuildConfig.class, sdk = 21,
manifest = "app/src/main/AndroidManifest.xml")
@RunWith(RobolectricGradleTestRunner.class)
public class RetrofitCallTest {
private MainActivity mainActivity;
@Mock
private RetrofitApi mockRetrofitApiImpl;
@Captor
private ArgumentCaptor<Callback<List<YourObject>>> callbackArgumentCaptor;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ActivityController<MainActivity> controller = Robolectric.buildActivity(MainActivity.class);
mainActivity = controller.get();
// Then we need to swap the retrofit api impl. with a mock one
// I usually store my Retrofit api impl as a static singleton in class RestClient, hence:
RestClient.setApi(mockRetrofitApiImpl);
controller.create();
}
@Test
public void shouldFillAdapter() throws Exception {
Mockito.verify(mockRetrofitApiImpl)
.getYourObject(callbackArgumentCaptor.capture());
int objectsQuantity = 10;
List<YourObject> list = new ArrayList<YourObject>();
for(int i = 0; i < objectsQuantity; ++i) {
list.add(new YourObject());
}
callbackArgumentCaptor.getValue().success(list, null);
YourAdapter yourAdapter = mainActivity.getAdapter(); // Obtain adapter
// Simple test check if adapter has as many items as put into response
assertThat(yourAdapter.getItemCount(), equalTo(objectsQuantity));
}
}
Run Code Online (Sandbox Code Playgroud)
通过右键单击测试类并按下运行继续测试.
就是这样.我强烈建议使用Robolectric(使用robolectric gradle插件)和Mockito,这些库使得测试Android应用程序变得更容易.我从以下博客文章中学到了这种方法.另外,请参阅此答案.
更新:如果您正在使用RxJava进行Retrofit,请查看我的其他答案.
Ada*_*gyi 20
如果使用.execute()而不是.enqueue(),它会使执行同步,因此测试可以正常运行,而无需导入3个不同的库并添加任何代码或修改构建变体.
喜欢:
public class LoginAPITest {
@Test
public void login_Success() {
APIEndpoints apiEndpoints = RetrofitHelper.getTesterInstance().create(APIEndpoints.class);
Call<AuthResponse> call = apiEndpoints.postLogin();
try {
//Magic is here at .execute() instead of .enqueue()
Response<AuthResponse> response = call.execute();
AuthResponse authResponse = response.body();
assertTrue(response.isSuccessful() && authResponse.getBearer().startsWith("TestBearer"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
JUnit 框架从不执行 CallBack 函数中的代码,因为主执行线程在检索到响应之前终止。您可以使用CountDownLatch如下所示:
@Test
public void testApiResponse() {
CountDownLatch latch = new CountDownLatch(1);
mApiHelper.loadDataFromBackend(new Callback() {
@Override
public void onResponse(Call call, Response response) {
System.out.println("Success");
latch.countDown();
}
@Override
public void onFailure(Call call, Throwable t) {
System.out.println("Failure");
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)这个测试样本也可能有帮助。
| 归档时间: |
|
| 查看次数: |
33001 次 |
| 最近记录: |