gpt4 book ai didi

Android AsyncTask 和 Mockito(或 PowreMockito)

转载 作者:太空宇宙 更新时间:2023-11-03 13:52:21 25 4
gpt4 key购买 nike

我有一个从远程服务器检索 json 的配置管理器。然后它被解析为一个 ConfigWrapper 对象,该对象在提供的回调监听器中作为参数返回。

所以在测试类中我调用:

@Test
public void init_Configuration_With_Network_Load_JSON_From_Server_Return_To_Listener() {

mockConnectivityCheck(true);

...

mManager.initConfiguration(mContext, eq(anyString()), mListener);

verify(mListener, times(1)).onConfigurationLoaded(any(ConfigWrapper.class));

}

mContext 被模拟,mListener 也被模拟。这将调用被测类的方法:

    public void initConfiguration(Context context, String url, ConfigurationManagerListener listener){
// Get a reference to shared preferences
mSharedPref = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);

// If we have network, we should load configurations from remote, otherwise, try to load it from assets folder OR shared pref
if (NetworkTools.hasNetworkConnection(context)){
getConfigurationRemote(context, url, listener);
} else {
getConfigurationOffline(context, listener);
}
}

所以如果我们有网络,我们可以从服务器获取配置。这个方法做到了:

private void getConfigurationRemote(final Context context, String url, final ConfigurationManagerListener
listener) {

// Send a request to get the configuration
new AsyncTask<String, Void, HashMap<String, Object>> () {

@Override
protected HashMap<String, Object> doInBackground(String... params) {
InputStream in = null;
HashMap result = null;
try {
URL url = new URL(params[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(10000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
in = conn.getInputStream();
result = new ObjectMapper().readValue(in, HashMap.class);
in.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null){
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}

return result;
}
}

@Override
protected void onPostExecute(HashMap<String, Object> config) {

// We if have a valid result, save the data to shared pref AND save it to a ConfigurationWrapper object
// other wise, try to load from assets folder or shared pref if available
if (config != null && config.size() > 0){

// We want to save the hierarchy of the JSON so we save its string representation to shared pref
JSONObject object = new JSONObject(config);
mSharedPref.edit().putString(CONFIGURATIONS_KEY, object.toString()).apply();
mConfigurationWrapper = new ConfigWrapper(config);
listener.onConfigurationLoaded(mConfigurationWrapper);
} else {
// No valid configuration from remote server, so load it from local source
getConfigurationOffline(context, listener);
}
}

}.execute(url);
}

现在,我正在尝试使用 Mockito(或 PowerMockito,如果需要)编写单元测试来测试此代码。我不完全确定如何解决这种情况,我调用的方法中有一个新的 AsyncTask().execute() 调用。到目前为止,调用 initConfiguration 方法并模拟网络检查返回 true,在调用 execute() 后停止。 doInBackground() 似乎没有被调用。

您将如何测试此类代码?谢谢!

最佳答案

代码的设置方式使单元测试变得困难。我建议重新安排它。

getConfigurationRemote 方法目前做 3 件独立的事情:

  • 创建AsyncTask
  • 定义该任务的作用
  • 执行任务

我的解决方案:

  • 将匿名 AsyncTask 移到它自己的类中。
  • 将任务的创建 (new AsyncTask(....) 移至工厂类,或者更好的是,使用依赖注入(inject)框架,如 Dagger

这就是我想象中的最终样子:

private void getConfigurationRemote(final Context context, String url, final ConfigurationManagerListener listener) {
// create the task
ConfigurationRemoteAsyncTask task = taskFactory.createConfigurationRemoteTask(listener);
// Send a request to get the configuration
task.execute(url);
}

现在您可以更轻松地模拟和测试:

  • 通过简单地模拟任务工厂返回的任务,验证在调用 .initConfiguration 时使用给定的 url 调用了 task.execute。

  • 验证在调用 task.onPostExecute 时调用了 listener.onConfigurationLoaded,而不模拟整个网络基础设施。这可能看起来像这样:

    @Test
    public void init_Configuration_With_Network_Load_JSON_From_Server_Return_To_Listener() {
    ConfigurationRemoteAsyncTask task = new ConfigurationRemoteAsyncTask(mockedListener);
    HashMap<String, Object> config = getNotEmptyConfig();
    task.onPostExecute(config);
    verify(mockedListener).onConfigurationLoaded(any(ConfigWrapper.class));
    }

关于Android AsyncTask 和 Mockito(或 PowreMockito),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33632389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com