使用mockito模拟请求/发布

Vic*_*ira 2 java testing unit-testing junit4 mockito

我在使用测试(JUnit/Mockito)覆盖以下函数“ postJson ”时遇到问题,并且无法找到模拟该行的方法response = getTarget(path).request().post(entity, Map.class);

\n\n
//Constructor\npublic HttpService() {\n    this.client = ClientBuilder.newClient();\n}\n\nClient client;\n\npublic Map<String, ?> postJson(String path, Map<String, ?> data){\n    Map<String, ?> response = null;\n\n    try {\n        Entity<Map<String, ?>> entity = Entity.entity(data, MediaType.APPLICATION_JSON);\n        response = getTarget(path).request().post(entity, Map.class);   \n    } catch (Exception e) {\n        LOG.error(e.toString());\n    }\n\n    return response;\n}\n\npublic WebTarget getTarget(String path){\n    return client.target(BASE_URI + path);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我目前的测试

\n\n
@Test\npublic void postJsonTest(){\n    assertEquals(null,new HttpService().postJson("", new HashMap<String,Integer>()));\n\n    //Verifica se a fun\xc3\xa7\xc3\xa3o de comunica\xc3\xa7\xc3\xa3o com servidor \xc3\xa9 chamda\n    Map<String,String> resposta = new HashMap<String,String>();\n    HttpService mock = spy(HttpService.class);  \n\n    assertEquals(mock.postJson("",resposta),null);\n\n    Mockito.verify(mock,Mockito.atLeast(1)).postJson("", resposta);\n    Mockito.verify(mock,Mockito.atLeast(1)).getTarget(Mockito.anyString());\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我找不到在“request()”之后编写测试代码的方法。任何人都可以给我一个例子/解释我如何用mockito覆盖这个函数?

\n

gly*_*ing 5

鉴于以下附加构造函数HttpService

public HttpService(Client client) {
    this.client = client;
}
Run Code Online (Sandbox Code Playgroud)

以下测试将通过:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 这依赖于提供一个HttpService接受Client实例的新构造函数。
  • 通过的无参数构造函数Client内的静态方法调用进行实例化的现有方法需要使用 PowerMockito。HttpService一种对测试更友好的方法是提供一个构造函数,它接受 aClient或可能ClientFactory是 a 的默认ClientFactory实现ClientBuilder.newClient()
  • postJson()方法具有链式调用 ( getTarget(path).request().post(entity, Map.class)) 的特点,它要求我们模拟该链中返回的每个对象ClientWebTargetRequestEntity
  • 我的示例跳过了具体细节,例如 的泛型类型RequestEntity以及精确参数匹配器与通用参数匹配器的选择。您将能够在那里做出正确的选择,因为您最了解(a)实现的细节和(b)测试的意图,但上面的测试至少表明模拟调用链需要每个对象在那个被嘲笑的链条中。