【发布时间】:2018-12-07 14:38:50
【问题描述】:
通过阅读,当您必须监视您正在单元测试的当前方法所使用的方法时,这通常是一种不好的做法和代码异味的迹象。
例如,我有一个正在单元测试的方法:
public MyResponseObject doStuff(MyRequestObject obj) {
WebTarget tar = getServiceClient().target(obj.toString());
Response res = tar.path(someURI).request().post(somejson);
if(response.getStatus() == 200) {
String jsonResp = response.readEntity(String.class);
return convertToObj(jsonResp);
}
}
我试图解决上述问题的一种方法是通过
- 将前两行(WebTarget、Response)提取到它自己的方法中,该方法返回一个 Response 对象。
- 创建一个 Response 的模拟并存根 readEntity 以返回 200 和 readEntity 以返回“OK”
结果如下:
public MyResponseObject doStuff(MyRequestObject obj) {
Response res = sendRequest(obj.toString());
if(response.getStatus() == 200) {
String jsonResp = response.readEntity(String.class);
return convertToObj(jsonResp);
}
}
//extracted method
public Response sendRequest(String json){
WebTarget tar = getServiceClient().target(someUrl);
return res = tar.path(someURI).request().post(somejson);
}
//My unit test
//sut is the system under test, setup elsewhere
public void testDoStuff() {
MyRequestObject request = ...;
Response respMock = mock(Response.class);
when(respMock.getStatus()).thenReturn(200);
when(respoMock.readEntity()).thenReturn("OK");
MyClass spy = spy(sut);
Mockito.doReturn(respMock).when(spy).sendRequest(requestString);
MyResponseObject response = spy.doStuff(request);
assertEquals(response.toString(),expectedResp);
}
如果我不把它存根,它会尝试执行一个真正的 HTTP 请求并返回一个无效的 URL 错误,因为我没有提供一个真正的错误 - 我相信这就是我想要的,因为我希望我的单元测试是独立于某些外部系统。
我应该以更好的方式进行单元测试吗?
【问题讨论】:
-
spy on method that is used by the current method you're unit testing下是什么意思? -
嗨,Oleksandr - 我用更详细的示例更新了我的帖子。希望这至少能澄清一点。
-
您可以: 1) 重构您的代码 - 将 http 传输层提取到单独的层中。 2)使用集成测试来测试http相关的东西 - 使用
wiremock- 它会模拟你的目标服务 - 你的代码将是透明的。
标签: java unit-testing testing mockito