提问人:Falling Into Infinity 提问时间:6/30/2019 最后编辑:questionaskerFalling Into Infinity 更新时间:7/12/2019 访问量:1533
测试涉及 AsyncTask 中的侦听器回调的类
Test a class that involves listener callback inside AsyncTask
问:
我正在尝试测试在AsyncTask
监听器类:
interface LoaderListener {
fun onByteSuccess(..., ..., ...)
fun onByteFailure(..., ...)
}
包含 AsyncTask 的类:
class Loader {
override fun handleStreamTask(){
InputStreamHandlingTask(..., ...).execute(byteArray)
}
private inner class InputStreamHandlingTask constructor(
internal var ...,
internal var ...
) : AsyncTask<ByteArray, Void, ByteArray>() {
override fun doInBackground(vararg params: ByteArray): ByteArray? {
val response = params[0]
.....
return response
}
override fun onPostExecute(byteArray: ByteArray?) {
if (byteArray != null) {
listener.onByteSuccess(..., ..., ...)
} else {
listener.onByteFailure(..., ...)
}
}
}
}
我正在尝试进行的测试:
@Test
fun testIfListenerCalled(){
val loader: Loader = mock()
val loaderListener: LoaderListener = mock()
loader.handleStreamTask()
verify(loaderListener).onByteSuccess(..., ..., ...)
}
我目前遇到的错误:
线程中的异常...java.lang.RuntimeException:未模拟在 android.os.AsyncTask 中执行的方法。有关详细信息,请参阅 http://g.co/androidstudio/not-mocked。 在 android.os.AsyncTask.execute(AsyncTask.java)
答:
1赞
ahasbini
7/12/2019
#1
如果这是在本地计算机上运行的单元测试,而不是在 Android 设备上运行的单元测试,则无法模拟依赖于 Android 框架的类,例如 .相反,应该将其实现为插桩测试,而不是在 Android 设备上运行的单元测试,或者使用可以在本地计算机上模拟 Android 框架的框架。AsyncTask
更多信息请见: https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests
评论
0赞
drdaanger
7/12/2019
这是正确的。要让测试在您的设备上运行,第一步是将测试从 test 目录移至 androidTest 目录。
0赞
Sachin Kasaraddi
7/12/2019
#2
下面的示例演示了如何在 JUnit 中测试 Asynctasks。
/**
* @throws Throwable
*/
public void testAsynTask () throws Throwable {
// create a signal to let us know when our task is done.
final CountDownLatch signal = new CountDownLatch(1);
/* Just create an in line implementation of an asynctask. Note this
* would normally not be done, and is just here for completeness.
* You would just use the task you want to unit test in your project.
*/
final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
//Your code to run in background thread.
return "Expected value from background thread.";
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
/* This is the key, normally you would use some type of listener
* to notify your activity that the async call was finished.
*
* In your test method you would subscribe to that and signal
* from there instead.
*/
signal.countDown();
}
};
// Execute the async task on the UI thread! THIS IS KEY!
runTestOnUiThread(new Runnable() {
@Override
public void run() {
myTask.execute("Do something");
}
});
/* The testing thread will wait here until the UI thread releases it
* above with the countDown() or 30 seconds passes and it times out.
*/
signal.await(30, TimeUnit.SECONDS);
// The task is done, and now you can assert some things!
assertTrue("Expected Value", true);
}
评论