fir*_*lud 0 java testing unit-testing mockito
通过阅读周围的内容,当您必须监视您正在单元测试的当前方法所使用的方法时,这通常是不好的做法,并且是代码异味的迹象。
例如,我有一个正在单元测试的方法:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试解决上述问题的一种方法是
结果如下:
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);
}
Run Code Online (Sandbox Code Playgroud)
如果我不将其存根,它会尝试执行真正的 HTTP 请求并返回无效的 URL 错误,因为我没有提供真正的 URL 错误 - 我相信这就是我想要的,因为我希望我的单元测试独立于某些外部系统。
我应该有更好的方法来进行单元测试吗?
是的,创建您正在测试的类的间谍是不好的做法,将您正在模拟的代码分解到另一个类中并模拟它,即:
public class MyClass {
private final MySender sender;
public MyClass() {
this(new DefaultSender());
}
public MyClass(MySender sender) {
this.sender = sender;
}
public MyResponseObject doStuff(MyRequestObject obj) {
Response res = sender.sendRequest(obj.toString());
if (response.getStatus() == 200) {
String jsonResp = response.readEntity(String.class);
return convertToObj(jsonResp);
}
}
public interface MySender {
Response sendRequest(String json);
}
private static class DefaultSender implements MySender {
public Response sendRequest(String json) {
WebTarget tar = getServiceClient().target(someUrl);
return res = tar.path(someURI).request().post(somejson);
}
}
}
@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
private MyClass testSubject;
@Mock
private MySender sender;
@Mock
private Response response;
@Test
public void testDoStuff() {
String expectedResp = ...;
MyRequestObject request = ...;
MyResponseObject response = testSubject.doStuff(request);
assertEquals(response.toString(),expectedResp);
}
@Before
public void setup() {
testSubject = new MyClass(sender);
when(sender.sendRequest(anyString()).thenReturn(response);
when(response.getStatus()).thenReturn(200);
when(response.readEntity()).thenReturn("OK");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3453 次 |
| 最近记录: |