模拟请求/用mockito发布 [英] Mock request/post with mockito

查看:430
本文介绍了模拟请求/用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.一种更易于测试的方法是提供一个接受ClientClientFactory的构造函数,并且ClientFactory的默认实现为ClientBuilder.newClient()
  • postJson()方法具有一个链式调用(getTarget(path).request().post(entity, Map.class)),该调用要求我们模拟该链中返回的每个对象,即ClientWebTargetRequestEntity
  • 我的示例介绍了诸如RequestEntity的泛型类型以及精确参数匹配器与常规参数匹配器的选择之类的细节.您将能够在那里做出正确的选择,因为您最了解(a)实现的细节和(b)测试的意图,但是上述测试至少表明,模拟调用链需要每个对象在该链中被嘲笑.
  • This relies on providing a new HttpService constructor which accepts a Client instance.
  • The existing approach of instancing Client via a static method call inside the HttpService's no-arg constructor requires use of PowerMockito. A more test friendly approach is to provide a constructor which accepts a Client or perhaps a ClientFactory with the default implementation of the ClientFactory being ClientBuilder.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 and RequestEntity
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆