Junit 如何在android中对异步任务进行单元测试
考虑下面的代码。我如何在不使用第三方库的情况下测试此功能?断言行永远不会执行,因为它是另一个线程,vm停止运行。非常感谢Junit 如何在android中对异步任务进行单元测试,junit,android-asynctask,android-junit,Junit,Android Asynctask,Android Junit,考虑下面的代码。我如何在不使用第三方库的情况下测试此功能?断言行永远不会执行,因为它是另一个线程,vm停止运行。非常感谢 public class FileParserTask extends AsyncTask<File, Void, ArrayList<City>> { private FileParserResult mResult; public interface FileParserResult { void onFinis
public class FileParserTask extends AsyncTask<File, Void, ArrayList<City>> {
private FileParserResult mResult;
public interface FileParserResult {
void onFinish(ArrayList<City> cities);
}
public FileParserTask(final FileParserResult result) {
mResult = result;
}
@Override
protected ArrayList<City> doInBackground(File... files) {
ArrayList<City> cities = new ArrayList<>();
try {
InputStream is = new FileInputStream(files[0]);
JsonReader reader = new JsonReader(new InputStreamReader(is, "UTF-8"));
reader.beginArray();
while (reader.hasNext()) {
City city = new Gson().fromJson(reader, City.class);
cities.add(city);
}
reader.endArray();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
Collections.sort(cities, (o1, o2) -> o1.getName().compareTo(o2.getName()));
mResult.onFinish(cities);
return cities;
}
}
正如您所说,问题在于异步任务通过
ExecutorService
在后台线程中运行。与Future
类似,它提供了一个get()
方法,该方法将等待并返回结果
new FileParserTask(cities -> {
Assert.assertEquals("Input should give back 200 results", 3, cities.size());
}).execute(file).get();
尽管您需要测试的代码:
Assert.assertEquals("Input should give back 200 results", 3, cities.size());
正在异步任务
中运行,这与单元测试无关AsyncTask
很可能已经过Google的广泛测试,因此您知道它将作为一个AsyncTask
工作。真正的测试似乎是需要在后台运行的功能,即doInBackground
中包含的业务逻辑
从业务逻辑的角度考虑,需要填充ArrayList
,并将其传播到应用程序。Android更喜欢在后台线程上完成这项工作,传播可以通过通知等方式处理,这两种方式都已经过测试,并由Google发布,因此您不需要在单元测试中包含它们。如何填充ArrayList
是真正的单元测试
AsyncTask
与集成测试相关,但您很可能要测试应用程序的另一个方面,即它显示的内容,而不是从后台线程接收的内容
因此,对于单元测试,我将重构
doInBackground
中的代码,以便它可以独立于Android希望它如何运行进行测试。对不起,您是否覆盖了AsyncTask的onPostExecute方法。
您将保留结果处理程序,但不会在任何地方使用它
@Override
protected void onPostExecute(Object result) {
mResult.processFinish(result);
}
至于这个断言,它看起来很好,因为它是。不,这不起作用。测试运行失败:由于“进程崩溃”,检测运行失败。这可能有助于忘记方法规范onPostExecute(ArrayList结果)中的类型
@Override
protected void onPostExecute(Object result) {
mResult.processFinish(result);
}