0

Hi!

I'm Unable to mock fetching data from GitHubApi To fetch data i use RestTemplate Exchange

Instead of taking data from github i want to mock my own

Expected :1
Actual   :11

Fetch Logic:

@Component
@Setter
public class GitHubApi {
    public List<GitHubRepository> getUserRepos(String user) {
        restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        addHeaders(headers);

         entity = new HttpEntity<>(headers);

        ResponseEntity<List<GitHubRepository>> response = restTemplate.exchange(
                GITHUB_API_URL + "/users/" + user + "/repos",
                HttpMethod.GET, entity,
                new ParameterizedTypeReference<List<GitHubRepository>>() {
                });
        return response.getBody();
    }
}

Test Logic:

    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private GitHubApi gitHubApi;

    @Test
    public void getUserRepos_ShouldReturnRepositories() {
        String username = "user";

        GitHubRepository mockedRepository = GitHubRepository.builder()
                .id(1L)
                .name("repo1")
                .fullName("user/repo1")
                .build();
        List<GitHubRepository> expected = List.of(mockedRepository);

        ResponseEntity<List<GitHubRepository>> mockResponse = new ResponseEntity<>(expected, HttpStatus.OK);

        HttpHeaders headers = new HttpHeaders();
        addHeaders(headers);

        when(restTemplate.exchange(
                eq(GITHUB_API_URL + "/users/" + username + "/repos"),
                eq(HttpMethod.GET),
                any(HttpEntity.class),
                eq(new ParameterizedTypeReference<List<GitHubRepository>>() {})
        )).thenReturn(mockResponse);

        List<GitHubRepository> repositories = gitHubApi.getUserRepos(username);

        assertNotNull(repositories);
        assertEquals(1, repositories.size());
        assertEquals("repo1", repositories.getFirst().getName());
    }
}

I tries removing eq and any, tried adding HttpEntity instead of any, same with ParameterizedTypeReference

3
  • This question is similar to: Why are my mocked methods not called when executing a unit test?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Feb 12 at 8:27
  • @knittl i've seen this solution and i couldnt solve my poroblem with this Commented Feb 12 at 13:25
  • It is exactly your problem: you are creating a new instance of RestTemplate inside your method ("annotating with @Mock does not help"). The @Mock annotated field of your test is independent from the instance in your method. Even the answer that you have accepted provides the same solution as in the linked duplicate ("Constructor Dependency Injection"). Commented Feb 12 at 13:37

1 Answer 1

1

In GitHubApi you create new instance of restTemplate inside method, so Mockito not injecting restTemplate to class.

You should make restTemplate as dependency:

@Component
@Setter
public class GitHubApi {
    private final restTemplate; // <-- Here rest template is declared as dependency of this class.

    // constructor or use @RequiredArgsConstructor if you use lombok.
    public GitHubApi(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    public List<GitHubRepository> getUserRepos(String user) {
        // do not create restTemplate here, because it will rewrite mock with another instance.
        HttpHeaders headers = new HttpHeaders();
        addHeaders(headers);

         entity = new HttpEntity<>(headers);

        ResponseEntity<List<GitHubRepository>> response = restTemplate.exchange(
                GITHUB_API_URL + "/users/" + user + "/repos",
                HttpMethod.GET, entity,
                new ParameterizedTypeReference<List<GitHubRepository>>() {
                });
        return response.getBody();
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.