监视 AsyncTask 不起作用
Spying an AsyncTask doesn't work
我正在测试 AsyncTask
。我想将 HttpURLConnection
存根到 return 我的模拟对象。我就是这样做的(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 return是真实的对象,不是模拟对象,我不明白为什么。
好吧,我找到了一个解决方案,但还没有找到它为何如此有效的解释。
没有工作的原因是 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;
}
}
我正在测试 AsyncTask
。我想将 HttpURLConnection
存根到 return 我的模拟对象。我就是这样做的(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 return是真实的对象,不是模拟对象,我不明白为什么。
好吧,我找到了一个解决方案,但还没有找到它为何如此有效的解释。
没有工作的原因是 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;
}
}