2
을 사용하여 단위 테스트를 위해 서버 응답을 모의합니다.OkHttp MockWebServer가 다시 시작될 때 연결을 허용하지 않습니다.
그것은 첫 번째 테스트를 위해 잘 작동하지만, 2 차 테스트에 내 클라이언트가 실패 : 0 : 0 : 0 : 0 : 0 : 0 : 1
이/0 localhost에 연결하지 못했습니다 : 63631
두 번째 테스트가 첫 번째 테스트와 완전히 동일 할 경우에도 발생합니다.
이@RunWith(RobolectricTestRunner.class)
@Config(shadows = MyClassTest.MyNetworkSecurityPolicy.class,
manifest = "src/main/AndroidManifest.xml",
constants = BuildConfig.class,
sdk = 16)
public class MyClassTest {
private MockWebServer mockServer;
private MyServerApi serverApi;
@Before
public void setUp() throws Exception {
System.out.println("\ntest start");
this.mockServer = new MockWebServer();
this.mockServer.start();
this.serverApi = new MyServerApi(this.mockServer.url("/").toString());
}
@Test
public void testOne() throws Exception {
final String responseBody = // read response from file
this.mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(responseBody));
final Waiter waiter = new Waiter();
this.serverApi.getData("some_id", new Callback<MyResponseData> {
@Override
public void onResponse(final Call<MyResponseData> call, final Response<MyResponseData> response) {
waiter.assertEquals("some_value", response.body().getValue());
waiter.resume();
}
@Override
public void onFailure(final Call<T> call, final Throwable error) {
waiter.fail(error);
}
});
waiter.await();
final RecordedRequest recordedRequest = this.mockServer.takeRequest();
assertEquals("GET", recordedRequest.getMethod());
}
@Test
public void testTwo() throws Exception {
final String responseBody = // read response from file
this.mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(responseBody));
final Waiter waiter = new Waiter();
this.serverApi.getData("some_id", new Callback<MyResponseData> {
@Override
public void onResponse(final Call<MyResponseData> call, final Response<MyResponseData> response) {
waiter.assertEquals("some_value", response.body().getValue());
waiter.resume();
}
@Override
public void onFailure(final Call<T> call, final Throwable error) {
waiter.fail(error);
}
});
waiter.await();
final RecordedRequest recordedRequest = this.mockServer.takeRequest();
assertEquals("GET", recordedRequest.getMethod());
}
@After
public void tearDown() throws Exception {
System.out.println("test end\n");
this.mockServer.shutdown();
}
@Implements(NetworkSecurityPolicy.class)
public static class MyNetworkSecurityPolicy {
@Implementation
public static NetworkSecurityPolicy getInstance() {
try {
Class<?> shadow = MyNetworkSecurityPolicy.class.forName("android.security.NetworkSecurityPolicy");
return (NetworkSecurityPolicy) shadow.newInstance();
} catch (Exception e) {
throw new AssertionError();
}
}
@Implementation
public boolean isCleartextTrafficPermitted() {
return true;
}
}
}
첫 번째 테스트가 정상적으로 통과하지만, 두 번째는 제가 위에서 쓴 메시지와 함께 실패합니다
는 여기에 내가 뭘하는지입니다. 콘솔에서
출력은 다음과 같습니다
test start
okhttp3.mockwebserver.MockWebServer$3 execute
INFO: MockWebServer[63631] starting to accept connections
WARNING: no system properties value for gsm.sim.operator.alpha
okhttp3.mockwebserver.MockWebServer$4 processOneRequest
INFO: MockWebServer[63631] received request: GET REQUEST_PATH HTTP/1.1 and responded: HTTP/1.1 200 OK
okhttp3.mockwebserver.MockWebServer$3 acceptConnections
test end
INFO: MockWebServer[63631] done accepting connections: Socket closed
test start
okhttp3.mockwebserver.MockWebServer$3 execute
INFO: MockWebServer[63649] starting to accept connections
okhttp3.mockwebserver.MockWebServer$3 acceptConnections
INFO: MockWebServer[63649] done accepting connections: Socket closed
on error: Failed to connect to localhost/0:0:0:0:0:0:0:1:63631
test end
이런 일이 발생하는 이유
어떤 생각합니다 (Waiter
오브젝트 것은 concurrentunit lib에서이다)?
흥미 롭지 만 그 이유는 알 수 없습니다. 각 테스트 메소드가 실행되기 전에'setUp' 메소드가 발생한다는 것을 알았습니다. 즉, 모의 서버의 새로운 인스턴스가 생성되고 새로 생성 된 모의 서버의 URL과 함께 내 서버 api의 새로운 인스턴스가 생성된다는 것을 의미합니다. 아니면 여기에 뭔가 빠졌나요? –
네, 맞아요. 예제처럼 간단하게 게시해서는 안되지만 실제 코드에서는 서버 API 인스턴스의 첫 번째 모의 서버 주소를 캐시합니다. 감사! –