How to use the wrapper class.
When I was writing test code, I wanted to mock the final class, so I made it a wrapper class. Originally it was a method that took a final class as an argument, but since it can not be tested with that, I decided to take an argument with a wrapper class. Wouldn't this have happened if we had developed test-driven from the beginning? .. .. difficult.
python
@Override
protected String doInBackground(URL... url) {
    HttpURLConnection con = null;
    URL urls = url[0];
    try {
        con = (HttpURLConnection)urls.openConnection();
        con.setRequestMethod("GET");
        con.connect();
        int resCd = con.getResponseCode();
        if (resCd != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP responseCode:" + resCd);
        }
        BufferedInputStream inputStream = new BufferedInputStream(con.getInputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        while (true) {
            line = reader.readLine();
            if (line == null) {
                break;
            }
            mBuffer.append(line);
        }
        inputStream.close();
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        con.disconnect();
    }
    return mBuffer.toString();
}
python
@Override
protected String doInBackground(URLWrapper... urlWrapper) {
    HttpURLConnection con = null;
    URLWrapper urls = urlWrapper[0];
    try {
        con = (HttpURLConnection)urls.openConnection();
        con.setRequestMethod("GET");
        con.connect();
        int resCd = con.getResponseCode();
        if (resCd != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP responseCode:" + resCd);
        }
        BufferedInputStream inputStream = new BufferedInputStream(con.getInputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        while (true) {
            line = reader.readLine();
            if (line == null) {
                break;
            }
            mBuffer.append(line);
        }
        inputStream.close();
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        con.disconnect();
    }
    return mBuffer.toString();
}
doInBackground is a method of AsyncTask. It's a subtle change, but at first I took java.net.URL as an argument, but I noticed that the URL is a final class and can not be mocked, so I changed it to a wrapper class. I also tried using PowerMockito, but it didn't work, so I'm using this for now. Now you can run the following test code.
python
@Test
public void test_doInBackground(){
    HttpURLConnection httpURLConnection = null;
    try{
        String rtnXml = "aaaaaaaaaaaa";
        //Mocking HttpURLConnection
        httpURLConnection = mock(HttpURLConnection.class);
        when(httpURLConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK);
        when(httpURLConnection.getInputStream()).thenReturn(new ByteArrayInputStream(rtnXml.getBytes("utf-8")));
        //URLWrapper mock
        URLWrapper urlWrapper = mock(URLWrapper.class);
        when(urlWrapper.openConnection()).thenReturn(httpURLConnection);
        //ConfirmAsyncListenerImpl mock
        ConfirmAsyncListenerImpl confirmAsyncListener = mock(ConfirmAsyncListenerImpl.class);
        // RestaurantAsync.doInBackground()a test of
        RestaurantAsync restaurantAsync = new RestaurantAsync(confirmAsyncListener);
        assertThat(restaurantAsync.doInBackground(urlWrapper), is("aaaaaaaaaaaa"));
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        httpURLConnection.disconnect();
    }
}
When I try to mock java.net.URL, I get a compile error, so I found that I can handle it by using a wrapper class.
By the way, the wrapper class is as follows
URLWrapper.java
public class URLWrapper {
    private final URL url;
    public URLWrapper(URL url){
        this.url = url;
    }
    public URLConnection openConnection(){
        URLConnection urlConnection = null;
        try {
            urlConnection =  this.url.openConnection();
        }catch(IOException e){
            e.printStackTrace();
        }
        return urlConnection;
    }
}
I wonder if there are any differences or disadvantages between taking an argument in the final class and taking it in its wrapper class. I will add it when I understand it again.
I will add it if I notice it again.
Recommended Posts