如何为单元测试创建 header 响应?
How can I create a header response for unit tests?
我有一些发送请求和接收响应的方法。我在 header 中收到响应,它是 String
.
我的方法:
@Override
public String myMethod(SomeClass someItem) {
try {
HttpRequest request = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofString(myBodyString))
.uri(getUri())
.header(OAUTH, getToken())
.headers(KEY_HEADER, valueHeader)
.headers(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
.build();
var response = httpClient.send(request, HttpBodyHandlers.ofCodec());
if (response.statusCode() == HttpStatus.OK.value()) {
return response.headers().allValues(LOCATION).get(0);
} else {
log.warn(ERROR_LOG + response.statusCode());
return null;
}
} catch (Exception e) {
log.error(ERROR_LOG + e.getCause());
return null;
}
}
我正在尝试在我的测试中断言此响应,但没有成功。
我的测试:
@ExtendWith(MockitoExtension.class)
class ClassToTest {
private final static String URL = "https://myUrl/";
private final static String ACCESS_TOKEN = "access_token";
private final Clock clock = Clock.fixed(Instant.now(), ZoneId.of("UTC"));
private ClassToTest service;
@Mock
private HttpClient httpClient;
@Mock
private OAuth oAuthClient;
@Mock
private HttpResponse httpResponse;
@BeforeEach
void setUp() {
service = new ClassToTest(httpClient, oAuthClient);
when(config.getValue(SERVICE_URL)).thenReturn(AVISO_URL);
when(oAuthClient.getToken()()).thenReturn(ACCESS_TOKEN);
}
@Test
void myMethod_toTest_success() throws IOException, InterruptedException {
when(httpClient.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class))).thenReturn(httpResponse);
when(httpResponse.statusCode()).thenReturn(HttpStatus.OK.value());
var result = service.myMethod(myItem);
assertEquals("UUID", result);
}
...
}
我无法为 assert
我的 result
创建 expected
项目。我的 result
得到了 null
我建议创建对象调用而不是模拟 HttpRespone 对象调用。 HttpResponse
具有相应值的对象
HttpResponse<String> httpResponse = new HttpResponse<String>() {
@Override
public int statusCode() {
return 200;
}
@Override
public HttpRequest request() {
return null;
}
@Override
public Optional<HttpResponse<String>> previousResponse() {
return Optional.empty();
}
@Override
public HttpHeaders headers() {
return HttpHeaders.of(Map.of("", List.of()), (v1,v2)->true);
}
@Override
public String body() {
return null;
}
@Override
public Optional<SSLSession> sslSession() {
return Optional.empty();
}
@Override
public URI uri() {
return null;
}
@Override
public HttpClient.Version version() {
return null;
}
};
在这种情况下模拟框架调用并没有多大好处,尽管这是可能的。您最终模拟了所有内容并复制了几乎所有的生产代码以匹配用法。
尝试使用类似 MockWebServer
的东西:
class ClassToTest {
private MockWebServer mockWebServer;
@BeforeEach
void init() {
this.mockWebServer = new MockWebServer();
when(config.getValue(SERVICE_URL))
.thenReturn(mockWebServer.url("/").toString());
// ...
}
@Test
void myMethod_toTest_success() {
mockWebServer.enqueue(new MockResponse()
.addHeader(LOCATION, "UUID")
.setBody("some response")
.setResponseCode(200));
var result = service.myMethod(myItem);
assertEquals("UUID", result);
}
}
启动 MockWebServer
的开销很小,但您的测试不必尝试复制 HttpClient
的真正作用。
我有一些发送请求和接收响应的方法。我在 header 中收到响应,它是 String
.
我的方法:
@Override
public String myMethod(SomeClass someItem) {
try {
HttpRequest request = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofString(myBodyString))
.uri(getUri())
.header(OAUTH, getToken())
.headers(KEY_HEADER, valueHeader)
.headers(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
.build();
var response = httpClient.send(request, HttpBodyHandlers.ofCodec());
if (response.statusCode() == HttpStatus.OK.value()) {
return response.headers().allValues(LOCATION).get(0);
} else {
log.warn(ERROR_LOG + response.statusCode());
return null;
}
} catch (Exception e) {
log.error(ERROR_LOG + e.getCause());
return null;
}
}
我正在尝试在我的测试中断言此响应,但没有成功。 我的测试:
@ExtendWith(MockitoExtension.class)
class ClassToTest {
private final static String URL = "https://myUrl/";
private final static String ACCESS_TOKEN = "access_token";
private final Clock clock = Clock.fixed(Instant.now(), ZoneId.of("UTC"));
private ClassToTest service;
@Mock
private HttpClient httpClient;
@Mock
private OAuth oAuthClient;
@Mock
private HttpResponse httpResponse;
@BeforeEach
void setUp() {
service = new ClassToTest(httpClient, oAuthClient);
when(config.getValue(SERVICE_URL)).thenReturn(AVISO_URL);
when(oAuthClient.getToken()()).thenReturn(ACCESS_TOKEN);
}
@Test
void myMethod_toTest_success() throws IOException, InterruptedException {
when(httpClient.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class))).thenReturn(httpResponse);
when(httpResponse.statusCode()).thenReturn(HttpStatus.OK.value());
var result = service.myMethod(myItem);
assertEquals("UUID", result);
}
...
}
我无法为 assert
我的 result
创建 expected
项目。我的 result
null
我建议创建对象调用而不是模拟 HttpRespone 对象调用。 HttpResponse
具有相应值的对象
HttpResponse<String> httpResponse = new HttpResponse<String>() {
@Override
public int statusCode() {
return 200;
}
@Override
public HttpRequest request() {
return null;
}
@Override
public Optional<HttpResponse<String>> previousResponse() {
return Optional.empty();
}
@Override
public HttpHeaders headers() {
return HttpHeaders.of(Map.of("", List.of()), (v1,v2)->true);
}
@Override
public String body() {
return null;
}
@Override
public Optional<SSLSession> sslSession() {
return Optional.empty();
}
@Override
public URI uri() {
return null;
}
@Override
public HttpClient.Version version() {
return null;
}
};
在这种情况下模拟框架调用并没有多大好处,尽管这是可能的。您最终模拟了所有内容并复制了几乎所有的生产代码以匹配用法。
尝试使用类似 MockWebServer
的东西:
class ClassToTest {
private MockWebServer mockWebServer;
@BeforeEach
void init() {
this.mockWebServer = new MockWebServer();
when(config.getValue(SERVICE_URL))
.thenReturn(mockWebServer.url("/").toString());
// ...
}
@Test
void myMethod_toTest_success() {
mockWebServer.enqueue(new MockResponse()
.addHeader(LOCATION, "UUID")
.setBody("some response")
.setResponseCode(200));
var result = service.myMethod(myItem);
assertEquals("UUID", result);
}
}
启动 MockWebServer
的开销很小,但您的测试不必尝试复制 HttpClient
的真正作用。