gpt4 book ai didi

java - Mockito:监视被测系统中依赖于 HTTP 请求的方法是不好的做法吗?

转载 作者:行者123 更新时间:2023-11-28 21:03:38 24 4
gpt4 key购买 nike

通过阅读,当您必须监视您正在单元测试的当前方法所使用的方法时,通常会出现不良做法和代码异味的迹象。

例如,我有这个正在单元测试的方法:

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);
}
}

我试图解决上述问题的一种方法是

  1. 将前两行(WebTarget、Response)提取到它自己的方法中,该方法返回一个 Response 对象。
  2. 创建 Response 的模拟并 stub readEntity 以返回 200 和 stub 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);
}

如果我不把它 stub ,它会尝试做一个真正的 HTTP 请求并返回一个无效的 URL 错误,因为我没有提供一个真正的错误——我相信这就是我想要的,因为我希望我的单元测试是独立于一些外部系统。

有没有更好的方法来进行我的单元测试?

最佳答案

是的,创建一个你正在测试的类的 spy 是不好的做法,将你正在模拟的代码分解到另一个类中并模拟它,即:

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");
}
}

关于java - Mockito:监视被测系统中依赖于 HTTP 请求的方法是不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53671685/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com