用 mockito 模拟 request/post
Mock request/post with mockito
我在使用测试 (JUnit/Mockito) 覆盖以下函数“postJson”时遇到问题,并且无法找到模拟行 [=13] 的方法=]
//Constructor
public HttpService() {
this.client = ClientBuilder.newClient();
}
Client client;
public Map<String, ?> postJson(String path, Map<String, ?> data){
Map<String, ?> response = null;
try {
Entity<Map<String, ?>> entity = Entity.entity(data, MediaType.APPLICATION_JSON);
response = getTarget(path).request().post(entity, Map.class);
} catch (Exception e) {
LOG.error(e.toString());
}
return response;
}
public WebTarget getTarget(String path){
return client.target(BASE_URI + path);
}
我目前正在测试
@Test
public void postJsonTest(){
assertEquals(null,new HttpService().postJson("", new HashMap<String,Integer>()));
//Verifica se a função de comunicação com servidor é chamda
Map<String,String> resposta = new HashMap<String,String>();
HttpService mock = spy(HttpService.class);
assertEquals(mock.postJson("",resposta),null);
Mockito.verify(mock,Mockito.atLeast(1)).postJson("", resposta);
Mockito.verify(mock,Mockito.atLeast(1)).getTarget(Mockito.anyString());
}
在 'request()' 之后,我找不到制作测试代码的方法。任何人都可以给我 example/explain 我怎样才能用 mockito 覆盖这个功能?
考虑到 HttpService
上的这个附加构造函数:
public HttpService(Client client) {
this.client = client;
}
以下测试将通过:
@RunWith(MockitoJUnitRunner.class)
public class HttpServiceTest {
@Mock
private Client client;
@Mock
private WebTarget webTarget;
@Mock
private RequestEntity requestEntity;
private HttpService httpService;
@Before
public void setUp() {
this.httpService = new HttpService(client);
}
@Test
public void postJsonTest() {
String path = "/a/path";
Map<String, ?> data = new HashMap<>();
// the postJson method features this chained call: getTarget(path).request().post(entity, Map.class)
// so we have to mock each object created in that chain
// covers getTarget(path)
Mockito.when(client.target(Mockito.anyString())).thenReturn(webTarget);
// covers request()
Mockito.when(webTarget.request()).thenReturn(requestEntity);
// covers post()
Map<String, Object> expected = new HashMap<>();
Mockito.when(requestEntity.post(Mockito.any(Entity.class), Mockito.eq(Map.class))).thenReturn(expected);
Map<String, ?> actual = httpService.postJson(path, data);
Assert.assertSame(expected, actual);
}
}
备注:
- 这依赖于提供一个接受
Client
实例的新 HttpService
构造函数。
- 通过
HttpService
的无参数构造函数中的静态方法调用实例化 Client
的现有方法需要使用 PowerMockito。一种对测试更友好的方法是提供一个接受 Client
或 ClientFactory
的构造函数,其中 ClientFactory
的默认实现是 ClientBuilder.newClient()
postJson()
方法具有链式调用 (getTarget(path).request().post(entity, Map.class)
) 的特点,它要求我们模拟该链中返回的每个对象,即 Client
、WebTarget
和 RequestEntity
- 我的示例略过了一些细节,例如
RequestEntity
的泛型类型以及精确参数匹配器与一般参数匹配器的选择。你将能够在那里做出正确的选择,因为你最了解(a)你的实现的细节和(b)你的测试的意图但是上面的测试至少告诉你模拟调用链需要每个对象在该链中被嘲笑。
我在使用测试 (JUnit/Mockito) 覆盖以下函数“postJson”时遇到问题,并且无法找到模拟行 [=13] 的方法=]
//Constructor
public HttpService() {
this.client = ClientBuilder.newClient();
}
Client client;
public Map<String, ?> postJson(String path, Map<String, ?> data){
Map<String, ?> response = null;
try {
Entity<Map<String, ?>> entity = Entity.entity(data, MediaType.APPLICATION_JSON);
response = getTarget(path).request().post(entity, Map.class);
} catch (Exception e) {
LOG.error(e.toString());
}
return response;
}
public WebTarget getTarget(String path){
return client.target(BASE_URI + path);
}
我目前正在测试
@Test
public void postJsonTest(){
assertEquals(null,new HttpService().postJson("", new HashMap<String,Integer>()));
//Verifica se a função de comunicação com servidor é chamda
Map<String,String> resposta = new HashMap<String,String>();
HttpService mock = spy(HttpService.class);
assertEquals(mock.postJson("",resposta),null);
Mockito.verify(mock,Mockito.atLeast(1)).postJson("", resposta);
Mockito.verify(mock,Mockito.atLeast(1)).getTarget(Mockito.anyString());
}
在 'request()' 之后,我找不到制作测试代码的方法。任何人都可以给我 example/explain 我怎样才能用 mockito 覆盖这个功能?
考虑到 HttpService
上的这个附加构造函数:
public HttpService(Client client) {
this.client = client;
}
以下测试将通过:
@RunWith(MockitoJUnitRunner.class)
public class HttpServiceTest {
@Mock
private Client client;
@Mock
private WebTarget webTarget;
@Mock
private RequestEntity requestEntity;
private HttpService httpService;
@Before
public void setUp() {
this.httpService = new HttpService(client);
}
@Test
public void postJsonTest() {
String path = "/a/path";
Map<String, ?> data = new HashMap<>();
// the postJson method features this chained call: getTarget(path).request().post(entity, Map.class)
// so we have to mock each object created in that chain
// covers getTarget(path)
Mockito.when(client.target(Mockito.anyString())).thenReturn(webTarget);
// covers request()
Mockito.when(webTarget.request()).thenReturn(requestEntity);
// covers post()
Map<String, Object> expected = new HashMap<>();
Mockito.when(requestEntity.post(Mockito.any(Entity.class), Mockito.eq(Map.class))).thenReturn(expected);
Map<String, ?> actual = httpService.postJson(path, data);
Assert.assertSame(expected, actual);
}
}
备注:
- 这依赖于提供一个接受
Client
实例的新HttpService
构造函数。 - 通过
HttpService
的无参数构造函数中的静态方法调用实例化Client
的现有方法需要使用 PowerMockito。一种对测试更友好的方法是提供一个接受Client
或ClientFactory
的构造函数,其中ClientFactory
的默认实现是ClientBuilder.newClient()
postJson()
方法具有链式调用 (getTarget(path).request().post(entity, Map.class)
) 的特点,它要求我们模拟该链中返回的每个对象,即Client
、WebTarget
和RequestEntity
- 我的示例略过了一些细节,例如
RequestEntity
的泛型类型以及精确参数匹配器与一般参数匹配器的选择。你将能够在那里做出正确的选择,因为你最了解(a)你的实现的细节和(b)你的测试的意图但是上面的测试至少告诉你模拟调用链需要每个对象在该链中被嘲笑。