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