模拟请求/用mockito发布 [英] Mock request/post with mockito
本文介绍了模拟请求/用mockito发布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我无法通过测试(JUnit/Mockito)覆盖以下函数' postJson ',并且找不到模拟行response = getTarget(path).request().post(entity, Map.class);
I am having trouble covering the following function 'postJson' with tests (JUnit/Mockito), and can't find a way to mock the line response = getTarget(path).request().post(entity, Map.class);
//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()'之后,我找不到一种方法来生成测试代码.任何人都可以给我一个示例/解释,我该如何使用Mockito覆盖此功能?
I can't find a way to make the test code after the 'request()' onwards. Anyone can give me an example/explain how I can go about covering this function with mockito ?
推荐答案
在HttpService
上给出此附加的构造函数:
Given this additional constructor on 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);
}
}
注意:
- 这依赖于提供一个新的
HttpService
构造函数,该构造函数接受Client
实例. - 通过
HttpService
的无参数构造函数内部的静态方法调用实例化Client
的现有方法需要使用PowerMockito.一种更易于测试的方法是提供一个接受Client
或ClientFactory
的构造函数,并且ClientFactory
的默认实现为ClientBuilder.newClient()
-
postJson()
方法具有一个链式调用(getTarget(path).request().post(entity, Map.class)
),该调用要求我们模拟该链中返回的每个对象,即Client
,WebTarget
和RequestEntity
- 我的示例介绍了诸如
RequestEntity
的泛型类型以及精确参数匹配器与常规参数匹配器的选择之类的细节.您将能够在那里做出正确的选择,因为您最了解(a)实现的细节和(b)测试的意图,但是上述测试至少表明,模拟调用链需要每个对象在该链中被嘲笑.
- This relies on providing a new
HttpService
constructor which accepts aClient
instance. - The existing approach of instancing
Client
via a static method call inside theHttpService
's no-arg constructor requires use of PowerMockito. A more test friendly approach is to provide a constructor which accepts aClient
or perhaps aClientFactory
with the default implementation of theClientFactory
beingClientBuilder.newClient()
- The
postJson()
method features a chained call (getTarget(path).request().post(entity, Map.class)
) which requires us to mock each object returned in that chain i.e.Client
,WebTarget
andRequestEntity
- My example skates over specifics such as the generic type of
RequestEntity
and the choice of exact argument matchers vs. general argument matchers. You'll be able to make the right choice there since you know most about (a) the specifics of your implementation and (b) the intention of your test but the above test at least shows you that mocking a chain of calls requires each object in that chain to be mocked.
这篇关于模拟请求/用mockito发布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文