0

I was trying to write a simple test for an API client that uses Spring RestTemplate for the HTTP call. The endpoint gives a byte[] back.

I want only to test the behaviour of my API client so I mocked this out by trying to return a known byte[] so that I can test that my API client behaves correctly.

When mocking <T> T getForObject(URI url, Class<T> responseType) of RestTemplate I can't get mockito to match the call with the any() matcher. The mock returns null instead.

I want to know:

  • if there is way to make mockito match the call
  • you have a good idea on how to make this work with another approach

Thanks for your input!

Below some minimal example code for the issue.

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;
import org.springframework.web.client.RestTemplate;

class ByteArrayTest {

  @Test
  void test() {
    byte[] expectedBytes = "expected byte array".getBytes();

    RestTemplate restTemplate = mock(RestTemplate.class);
    when(restTemplate.getForObject(any(), any())).thenReturn(expectedBytes);

    byte[] actualBytes = restTemplate.getForObject("http://localhost", byte[].class);
    assertEquals(expectedBytes, actualBytes);

  }
}
ramses728
  • 323
  • 2
  • 12
  • Have yuo tried `any(byte[].class)` instead of `any()`? – M. Deinum Feb 07 '23 at 10:51
  • Does this answer your question? [Mockito matching primitive types](https://stackoverflow.com/questions/49618362/mockito-matching-primitive-types) – Dimitris Feb 07 '23 at 10:53
  • Also, https://stackoverflow.com/questions/21980728/mockito-for-int-primitive/53331588 – Dimitris Feb 07 '23 at 10:53
  • Why are you asserting your mock? That test doesn't test any real behavior, it only tests mocks. – knittl Feb 07 '23 at 11:49
  • Hi , thanks for the replies. Here my ansewers in short: `any(byte[].class)` unfortunately does not work, the example is geared towards simulating the response from the RestTemplate it does not cover the actual testing that I want to do just the mocking that does not what I expected, the questions with primitives have also not being fruitful as the passed type is `Class`. The last point provides me with food for thought though – ramses728 Feb 07 '23 at 13:03

1 Answers1

0

Turns out that the signature that I actually wanted to mock is:

public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)

The vararg uriVariables made it look like a 2 argument version of getForObject() in the code I was referencing.

Suppling the a vararg compatible matcher like ArgumentMatchers.<Object>any() makes it work.

The following example works as we match the correct signature.

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;
import org.springframework.web.client.RestTemplate;

class ByteArrayTest {

  @Test
  void test() {
    byte[] expectedBytes = "expected byte array".getBytes();

    RestTemplate restTemplate = mock(RestTemplate.class);
    when(restTemplate.getForObject(any(), any(), ArgumentMatchers.<Object>any())).thenReturn(expectedBytes);

    byte[] actualBytes = restTemplate.getForObject("http://localhost", byte[].class);
    assertEquals(expectedBytes, actualBytes);

  }
}
ramses728
  • 323
  • 2
  • 12