模拟类方法的NullPointerException

时间:2017-06-07 10:14:12

标签: java testing mockito

我目前正在为购买类Buy的方法编写测试,该测试应该实际测试是否正确的请求是否发送到服务器以及它是否正确处理了响应。

目前我总是收到java.lang.NullPointerException,因为execute(post)返回null而不是CloseableHttpResponse。

  

CloseableHttpResponse response = httpClient.execute(post);

但我不明白,因为在我的测试中,我告诉mockito返回模拟的closeableHttpResponse。

测试

  @Test
    public void testBid() throws IOException {
        //given:
        HttpPost post = mock(HttpPost.class);
        HttpResponse httpResponse = mock(HttpResponse.class);

        StatusLine statusLine = mock(StatusLine.class);

        ObserverImp observer = mock(ObserverImp.class);

        CloseableHttpClient closeableHttpClient = mock(CloseableHttpClient.class);
        CloseableHttpResponse closeableHttpResponse = mock(CloseableHttpResponse.class);
        HttpEntity httpEntity = mock(HttpEntity.class);
        BufferedInputStream inputStream = mock(BufferedInputStream.class);

        //and:
        when(statusLine.getStatusCode()).thenReturn(200);
        when(httpResponse.getStatusLine()).thenReturn(statusLine);
        when(closeableHttpClient.execute(post)).thenReturn(closeableHttpResponse);
        when(closeableHttpResponse.getEntity()).thenReturn(httpEntity);
        when(httpEntity.getContent()).thenReturn(inputStream);
        when(inputStream.read()).thenReturn(1);
        when(observer.getKey()).thenReturn("##213");


        Buy buy = new Buy(observer, closeableHttpClient);
        buy.bid(14455);
    }

相关的实施

public class Buy {
    private ObserverImp observer;
    private CloseableHttpClient httpClient;

    public Buy (ObserverImp observer, CloseableHttpClient httpClient) {
       this.observer = observer;
       this.httpClient = httpClient;
    }

    public void buy(double price) {
            String queryArgs = "command=order&amount=1" + "&price=" + String.valueOf(price); // generates query

            HttpPost post = new HttpPost("wwww.hm.edu/projectGroup1");
            post.addHeader("Key", observer.getKey());
            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("amount", "1"));
            params.add(new BasicNameValuePair("price", String.valueOf(price)));
            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");
            }
        }
}

请帮我解决这个问题。非常感谢你。

2 个答案:

答案 0 :(得分:2)

你需要:

  

当(closeableHttpClient.execute(任何(HttpPost.class)))thenReturn(closeableHttpResponse);

您的代码在等待您在测试中创建的确切帖子(等于)之前。但你的购买方法会产生另一个帖子。这就是为什么你的执行(post)与班级不匹配的原因。 any()解决了

答案 1 :(得分:0)

您需要设置返回类型,默认情况下,null将从模拟返回。另外在实现中调用createDefault http对象。