我正在嘗試改進一些單元測試,所以我使用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