我正在测试一个AsyncTask
。我想存根一个HttpURLConnection
以返回我的模拟对象。这就是我的做法(PackageDownloader
代表一个AsyncTask
(:
...
PackageDownloader packageDownloader = new PackageDownloader();
packageDownloader.setParameters(URL, downloadFolder, downloadProgressCallback);
PackageDownloader mPackageDownloader = spy(packageDownloader);
HttpURLConnection connectionMock = Mockito.mock(HttpURLConnection.class);
doReturn(0).when(connectionMock).getContentLength();
doReturn(connectionMock).when(mPackageDownloader).createConnection(Mockito.any(URL.class));
mPackageDownloader.execute();
mPackageDownloader.get();
这是PackageDownloader
:
public HttpURLConnection createConnection(URL url) throws IOException {
HttpURLConnection connection;
connection = (HttpURLConnection) url.openConnection();
return connection;
}
@Override
protected DownloadResult doInBackground(Void... params) {
HttpURLConnection connection;
URL downloadUrl = new URL(downloadUrlString);
connection = createConnection(downloadUrl);
long totalBytes = connection.getContentLength();
...
在这里,createConnection 返回真实的,而不是模拟的对象,我不知道为什么。
好吧,我已经找到了一个解决方案,尽管还没有找到为什么它会如此工作的解释。没有任何效果的原因是doInBackground
方法是异步的,我假设,所以我不得不通过反射直接调用它,如下所示:
Method method = mPackageDownloader.getClass().getMethod("doInBackground", Void[].class);
method.invoke(mPackageDownloader, new Void[] {null});
您可以使用 robolectric 来测试异步任务而不是反射。遵循ShadowApplication.runBackgroundTasks()
应调用doInBackground()
方法。
@RunWith(RobolectricTestRunner.class)
public class AcknowledgeAppRemovedTaskTest {
@Test
public void execute_shouldOpenInputStreamOfConnection() throws IOException {
DownloadTask spy = spy(new DownloadTask());
HttpURLConnection connectionMock = mock(HttpURLConnection.class);
doReturn(connectionMock).when(spy).createConnection(any(URL.class));
spy.execute();
ShadowApplication.runBackgroundTasks();
verify(connectionMock).getInputStream();
}
}
class DownloadTask extends AsyncTask<Void, Void, Void> {}
public HttpURLConnection createConnection(URL url) throws IOException {
return (HttpURLConnection) url.openConnection();
}
@Override
protected Void doInBackground(Void... voids) {
try {
HttpURLConnection urlConnection = createConnection(new URL("https://www.google.com/"));
urlConnection.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
https://github.com/robolectric/robolectric/blob/master/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskTest.java
https://groups.google.com/forum/#!topic/mockito/mqF21aqTi5g