how to mock restTemplate getForObject

2019-08-21 11:50发布

问题:

I want to test the restTemplate.getForObject method using a mock but having issues. I'm new with Mockito, so I read some blogs about testing restTemplate using Mockito but still can not write a successful test. The class to test is :

package rest;

@PropertySource("classpath:application.properties")
@Service
public class RestClient {

    private String user;
    // from application properties
    private String password;
    private RestTemplate restTemplate;

    public Client getClient(final short cd) {

        restTemplate.getInterceptors().add(new BasicAuthenticationInterceptor(user, password));

        Client client = null;

        try {
            client = restTemplate.getForObject("http://localhost:8080/clients/findClient?cd={cd}",
                    Client.class, cd);
        } catch (RestClientException e) {

            println(e);
        }

        return client;
    }

    public RestTemplate getRestTemplate() {
        return restTemplate;
    }

    public void setRestTemplate(final RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
}

My test class :

package test;
@PropertySource("classpath:application.properties")
@RunWith(MockitoJUnitRunner.class)
public class BatchRestClientTest {


    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private RestClient restClient;

    private MockRestServiceServer mockServer;

    @Before
    public void setUp() throws Exception {
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void getCraProcessTest() {
        Client client=new Client();
        client.setId((long) 1);
        client.setCd((short) 2);
        client.setName("aaa");

        Mockito
            .when(restTemplate.getForObject("http://localhost:8080/clients/findClient?cd={cd},
                    Client.class, 2))
            .thenReturn(client);

        Client client2= restClient.getClient((short)2);
        assertEquals(client, client2);
    }

    public RestTemplate getRestTemplate() {
        return restTemplate;
    }

    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public RestClient getRestClient() {
        return restClient;
    }

    public void setRestClient(RestClient restClient) {
        this.restClient = restClient;
    }
}

It is returning null and not the expected client, the restTemplate for Object class works fine. I want just to write the test . Am I missing something or doing the test wrong way? Thanks for any guidance.

回答1:

Use this instead:

Mockito.when(restTemplate.getForObject(
    "http://localhost:8080/clients/findClient?cd={id}",
    Client.class,
    new Object[] {(short)2})
).thenReturn(client);

The third parameter is a varargs. So you need to wrap into an Object[] in the test, otherwise Mockito is not able to match it. Note that this happens automatically in your implementation.

Also:

  • You forgot to terminate your url (missing closing ") in your examples in the question.
    Probably just a typo.

  • You used different url's in your implementation in your test: ...?cd={cd} instead of ...?cd={id}.
    (As previously pointed out by @ArnaudClaudel in the comments).

  • You did not define a behaviour for restTemplate.getInterceptors()
    so I would expect it to fail with a NullPointerException,
    when trying to add the BasicAuthenticationInterceptor.


Additionally you might want to check my answer here for another example of how to mock the getForObject method. Note that it does not include a case where any of the real parameters would be null.



标签: junit mockito