Android asynctask and mockito (or powre mockito)

I have a configuration manager that can retrieve JSON from the remote server, parse it into a configwrapper object, and return the object as a parameter in the provided callback listener

Therefore, in the test course, I call it:

@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 and mlistener are simulated. This will call the method of the tested class:

    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);
        }
    }

Therefore, if we have a network, we can get the configuration from the server. This method does the following:

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);
}

Now, I'm trying to write a unit test that can test this code using mockito (or powermockito, if necessary). I'm not completely sure how to solve this situation. In this case, I'll call the method with the new asynctask(). Execute(). So far, after calling execute(), Will stop calling the initconfiguration method and simulate a network check to return true. Doinbackground() does not appear to have been called

How would you test such code? thank you!

resolvent:

The way the code is set up makes unit testing difficult. I suggest rescheduling it

The getconfigurationremote method currently performs three separate operations:

>Create asynctask > define the role of the task > execute task

My solution:

>Move the anonymous asynctask to its own class. > move the creation of the task (New asynctask (...) to the factory class, or preferably use a dependency injection framework such as dagger

This is what I finally imagined:

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);
}

Now you can simulate and test more easily:

>By simply simulating the task returned by the task factory, verify whether task.execute is called with the given URL when calling. Initconfiguration. > verify whether listener.onconfigurationloaded is called when calling task.onpostexecute without simulating the entire network infrastructure. It may look like this:

@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));
}

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>