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