关于java:使用传出的HTTP请求测试void方法

Test a void method with an outgoing HTTP request

我在SO处查看了一些较旧的问题,你们大多数人都说,不要测试一个无效的方法。

我有一个方法,它发送一个HTTP请求到服务器,我想我仍然应该测试,即使该方法是无效的? 如果没有,请告诉我为什么,因为dzone的许多教程都提到你应该测试休息请求。

如果我应该测试它,请帮助我回答我必须测试的内容以及我是如何做到的,因为void无法返回任何内容。 如果你看到另一个没有去,请告诉我,我想尽可能多地改进。

这是方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
private void buy(double price) {
    final String timestamp = String.valueOf(System.currentTimeMillis());
    final String amount = String.valueOf(observer.requestedAmount);
    final String ressouce = GetValuesTypes.getRessource("user").get(observer.getRelatedUser);

    String queryArgs ="wwww.doSomething.com/" + ressouce;
    String hmac512 = HMAC512.hmac512Digest(queryArgs);

    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpPost post = new HttpPost(GetValuesTypes.getURL());
    post.addHeader("Key", GetValuesTypes.getKey());
    post.addHeader("Sign", hmac512);
    try {
        post.setEntity(new ByteArrayEntity(queryArgs.getBytes("UTF-8")));
    } catch (UnsupportedEncodingException e) {
        System.out.println("Exception in run");
    }
    List<NameValuePair> params = new ArrayList<>();

    params.add(new BasicNameValuePair("command","order"));
    params.add(new BasicNameValuePair("ressource", ressource));
    params.add(new BasicNameValuePair("rate", String.valueOf(rate)));
    params.add(new BasicNameValuePair("amount", amount));
    params.add(new BasicNameValuePair("timestamp", timestamp));
    try {
        post.setEntity(new UrlEncodedFormEntity(params));
        CloseableHttpResponse response = httpClient.execute(post);
        HttpEntity entity = response.getEntity();
        Scanner in = new Scanner(entity.getContent());
        String orderNumber ="";
        while (in.hasNext()) {
            orderNumber = in.nextLine();
        }
        String[] findOrderNumber = orderNumber.split(".");
        long lastOrderNumber = -1;
        try {
            lastOrderNumber = Long.valueOf(findOrderNumber[3]);
        } catch (NumberFormatException exception) {
            System.out.println("NumberFormatException");
        } finally {
            if (lastOrderNumber != -1) {
                observer.setOrderNumber(lastOrderNumber);
            }
        }
        in.close();
        EntityUtils.consume(entity);
        httpClient.close();
    } catch (IOException e) {
        System.out.println("Exception occured during process");
    }
}


您不应该直接测试private方法。相关主题:

  • 如何测试具有私有方法,字段或内部类的类?
  • 我应该测试私有方法还是仅测试公共方法?
  • 我应该如何在Java中测试私有方法?
  • 你如何对私人方法进行单元测试?

但是,如果您正在测试并且需要对其进行模拟,则可以使用PowerMock - Java框架,该框架允许您对通常被视为不可测试的代码进行单元测试。代码示例:使用PowerMock的Mockito Mock私有方法示例


void方法不返回任何内容,但您有办法测试它。

以下是两种主要方法:

  • 一种有意义的方法:检查方法实现产生的副作用。一种方法什么都不做。因此,您可以检查它是否应该执行此操作。

  • 一种不太有意义的方法:检查方法的依赖关系,因为应该调用它们。最后你什么都没试过。
    例如,您只需检查/断言使用对象b调用方法a,并将其结果用作方法c作为其参数。
    这是一个记录模拟行为和测试记录被调用的测试。它不可读,您可以错误地记录任何行为,而不会在测试中看到错误。

在可能的情况下,单元测试应该支持输入(我想测试的数据)和输出(我期望拥有的数据)原则。

这就是为什么我赞成第一种方式。

在您的情况下,您的void方法生成的输出似乎是:

1
2
3
if (lastOrderNumber != -1) {
    observer.setOrderNumber(lastOrderNumber);
}

在单元测试中,您应该有办法获取observer字段。
通过这种方式,您可以断言它包含您期望的订单号。