Anna Klein
Anna Klein

Reputation: 2151

NullPointerException at mocked class method

I am currently writing a test for the method buy of the class Buy which should actually test if the correct request is going to the server and if it's handling the response correctly.

At the moment I always receive a java.lang.NullPointerException because execute(post) returns null instead of the CloseableHttpResponse.

CloseableHttpResponse response = httpClient.execute(post);

But I don't understand because in my test I tell mockito to return the mocked closeableHttpResponse.

The test

  @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);
    }

And the related Implementation

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");
            }
        }
}

Please help me to fix that issue. Thank you a lot.

Upvotes: 1

Views: 2004

Answers (2)

PowerFlower
PowerFlower

Reputation: 1619

You need that:

when(closeableHttpClient.execute(any(HttpPost.class))).thenReturn(closeableHttpResponse);

Your code before just waits for the exact post (equals) that you created in your test. But your buy method produces another post. Thats why your execute(post) cannot match the class. any() solves that

Upvotes: 2

anshul Gupta
anshul Gupta

Reputation: 1270

You need to set the return type, by default null will be returned from the mock. Also in the implementation call createDefault http object.

Upvotes: 0

Related Questions