我正在尝试改进一些单元测试,所以我使用mockito来模拟一些对象。所以现在我有两个问题:我应该尝试模拟一个AsyncTask和(如果是的话)如何使用这个模拟对象调用模拟对象的方法doInBackground()
?如何使用Mockito进行AsyncTask模拟?
我已经尝试了几件事,但它仍然无法正常工作。我的测试仍然给我一个断言失败:
如何执行的AsyncTask(在StudioActivity.java):
.....
LocationTask task = new LocationTask();
task.execute((LocationManager) this.getSystemService(Context.LOCATION_SERVICE));
我的异步任务(在StudioActivity.java):
.....
public class LocationTask extends AsyncTask<LocationManager, Void, String> {
private LocationManager mLocationManager;
// private TextView mLocText;
@Override
protected void onPreExecute() {
super.onPreExecute();
// mLocText = (TextView) findViewById(R.id.textView_location);
// mLocText.setVisibility(View.VISIBLE);
}
@Override
public String doInBackground(LocationManager... params) {
mLocationManager = params[0];
Location loc = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Geocoder gcd = new Geocoder(getApplicationContext(), Locale.getDefault());
List<Address> addresses;
try {
addresses = gcd.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
if (addresses.size() > 0) {
return (addresses.get(0).getLocality() + ", " + addresses.get(0).getCountryName());
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
mPreviewFragment.setLocation(result);
mLocation = result;
}
}
这就是我试过的。
我的测试方法(在TestStudioActivity.java):
@UiThreadTest
public void testGeolocalistationLabel() throws InterruptedException, ExecutionException{
LocationTask mockLocationTask = mock(StudioActivity.LocationTask.class);
when(mockLocationTask.doInBackground((LocationManager[]) any())).thenReturn("JUnit, Location");
mStudioBoastPreviewFragment.getGeoloc().performClick();
assertEquals("JUnit, Location",mStudioBoastPreviewFragment.getGeolocTextView().getText());
verify(mockLocationTask).doInBackground((LocationManager[]) any());
}
OR
@UiThreadTest
public void testGeolocalistationLabel() throws InterruptedException, ExecutionException{
LocationTask mockLocationTask = mock(StudioActivity.LocationTask.class);
when(mockLocationTask.doInBackground((LocationManager) mStudioActivity.getSystemService(Context.LOCATION_SERVICE))).thenReturn("JUnit, Location");
mStudioBoastPreviewFragment.getGeoloc().performClick();
assertEquals("JUnit, Location",mStudioBoastPreviewFragment.getGeolocTextView().getText());
verify(mockLocationTask).doInBackground((LocationManager) mStudioActivity.getSystemService(Context.LOCATION_SERVICE));
}
失败的原因:
junit.framework.AssertionFailedError: expected:<JUnit, Location> but was:<>
at com.c4mprod.bhost.test.TestStudioActivity.testGeolocalistationLabel(TestStudioActivity.java:255)
没有嘲讽,它的工作。但是这个测试的执行时间很长。这就是为什么我想要使用Mockito:提高测试速度并避免连接问题或服务器错误。我只想测试该位置是否显示在mStudioBoastPreviewFragment.getGeolocTextView()
中。
在这两种情况下,我有一个声明失败,所以我想知道哪种方法是最好的,我怎么可以用它来嘲笑这个doInBackground()
。或者如果有另一种方法模拟AsyncTask。
感谢您的帮助!
我不确定是否正确理解您的测试。你想要测试什么课程? “mStudioBoastPreviewFragment”还是LocationTask?我看不到你的模拟LocationTask如何被注入到“mStudioBoastPreviewFragment”中。从所有我可以看到你的模拟LocationTask是根本不使用。 – joerx
@joerx mStudioBoastPreviewFragment是一个包含我想测试的TextView的片段。此片段是名为StudioActivity的Activity的一部分,LocationTask是StudioActivity的内部类。当我点击StudioBoastPreviewFragment中的ToggleButton时,这将启动AsyncTask,LocationTask,它将geoloc用户并在我之前提到的TextView中显示其位置。所以要回答你的问题:我正在测试的类是StudioBoastPreviewFragment。 – GiyommStarsky