user1902183
user1902183

Reputation: 3377

Mocking RestTemplate call with Mockito

I have the following code that is inside of a method that I am testing. I need to mock this restTemplate call to get predictable result.

GitHubEmail[] gitHubEmails = restTemplate
        .getForObject(userEmailsUrl, GitHubEmail[].class, oAuthToken);

In the test method, I do this:

RestTemplate mockRestTemplate = Mockito.mock(RestTemplate.class);

GitHubEmail fakeGitHubEmail = new GitHubEmail("[email protected]", 
                                 false, false, GitHubEmailVisibility.PRIVATE);
    GitHubEmail[] fakeEmails = {fakeGitHubEmail};

    Mockito.when(mockRestTemplate.getForObject(
                     Mockito.eq(userUrl), 
                     Mockito.eq(GitHubEmail[].class),
                     Mockito.eq(testOAuthToken)))
           .thenReturn(fakeEmails);

    gitHubService.setRestTemplate(mockRestTemplate);
    User user = gitHubService.getUser(testOAuthToken);

Things aren't working as I expect them to... When I examine gitHubEmails variable in my method I am testing, it's null.

Why isn't this working?

Upvotes: 1

Views: 2585

Answers (1)

Dimitri Mestdagh
Dimitri Mestdagh

Reputation: 44745

The current code as it is right now does not contain any mistakes. However, there are two things we don't see from the given code:

  1. We don't see that testOAuthToken is properly passed to the oAuthToken variable within the githubService.
  2. We don't see that the userUrl is passed to the userEmailsUrl within githubService.

You should make sure that all properties match the one you expect them to be, otherwise the mocking doesn't work. Given that you named one property userUrl and the other one userEmailsUrl, it's likely that the error is there.

Usually, when I encounter these error-prone mocking situations, I use "any matchers" (any(), anyString(), ...) when mocking and then after the call and the assertions, I use Mockito.verify() to check if the parameters match:

Mockito.when(mockRestTemplate.getForObject(
        Mockito.anyString(), // Use anyString()
        Mockito.eq(GitHubEmail[].class),
        Mockito.anyString())) // Use anyString()
    .thenReturn(fakeEmails);

// Call + Assertions ...

Mockito.verify(mockRestTemplate).getForObject(
    Mockito.eq(userUrl), // Use eq()
    Mockito.eq(GitHubEmail[].class),
    Mockito.eq(testOAuthToken)); // Use eq()

The reason for this is that the verify() output gives a lot more feedback. Rather than just failing, it will tell why it failed when:

  • The mocked method was called with different arguments, and which arguments
  • The mocked object had different methods being invoked

Upvotes: 1

Related Questions