私はURLを取って、getリクエストを介してこのURLからデータを取得する簡単な方法を書いています。このメソッドは次のようになります。PowerMockが正しく模倣しない
public String getResponse(String connectionUrl) throws HttpException {
HttpURLConnection connection = null;
try {
URL url = new URL(connectionUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode != 200) {
throw new HttpException("Response code was " + responseCode + " (should be 200)");
}
Scanner scanner = new Scanner(connection.getInputStream()).useDelimiter("\\A");
String response = scanner.hasNext() ? scanner.next() : "";
connection.disconnect();
scanner.close();
return response;
} catch (IOException e) {
if (connection != null) {
connection.disconnect();
}
throw new HttpException(e.getMessage(), e.getCause());
}
}
このメソッドの単体テストを記述しています。私はMockitoとJUnitでPowerMockを使ってテストを書いています。問題のテストは、次のようになります。
@Test
public void getResponse_NormalResponse() throws Exception {
String expectedResponse = "This is the expected response text!";
URL url = PowerMockito.mock(URL.class);
HttpURLConnection connection = PowerMockito.mock(HttpURLConnection.class);
InputStream inputStream = PowerMockito.mock(InputStream.class);
Scanner scanner = PowerMockito.mock(Scanner.class);
PowerMockito.whenNew(URL.class).withArguments(REQUEST_URL).thenReturn(url);
PowerMockito.whenNew(Scanner.class).withArguments(inputStream).thenReturn(scanner);
PowerMockito.when(url.openConnection()).thenReturn(connection);
// Response code mocked here
PowerMockito.when(connection.getResponseCode()).thenReturn(200);
PowerMockito.when(connection.getInputStream()).thenReturn(inputStream);
PowerMockito.when(scanner.hasNext()).thenReturn(true);
PowerMockito.when(scanner.next()).thenReturn(expectedResponse);
HttpClient httpClient = new HttpClient();
String actualResponse = httpClient.getResponse(REQUEST_URL);
Assert.assertEquals("Response is wrong!", expectedResponse, actualResponse);
}
しかし、私は、テストを実行すると応答コードはテストがPowerMockRunnerで実行されている404であるので、HttpExceptionがスローされます。何が間違っていたのですか、なぜこのテストは正しく動作していませんか?あなたは(あなたがwhenNew
を使用し、各クラスの)オブジェクトの作成をモックとしたいとき、それぞれのケースのためにそれを追加する必要があり
@PrepareForTest({URL.class, Scanner.class})
:
私は、PowerMockなしでテストできるようにメソッドコードをリファクタリングすることをお勧めします。多くの変更はありません。 –
変更することをお勧めしますか? –
ヒント:PowerMockを使用するのではなく、他のより理想的なアイデアは、単にあなたのメソッドで新しい呼び出しを行わない**ことです。テストするのが難しいコードを作成すると、テストするのが難しいときは驚かないでください。 https://www.youtube.com/playlist?list=PLD0011D00849E1B79 – GhostCat