Reputation: 783
I have simple spring boot application with Controller
,Service
,Business
and Util
classes, so I'm trying to mock the method in MockUtil
bean which takes four parameters but it returns null
MockMainController
@RestController
public class MockMainController {
@Autowired
private MockBusiness mockBusiness;
@GetMapping("request")
public MockOutput mockRequest() {
return mockBusiness.businessLogic(new MockInput());
}
}
MockBusiness
@Service
public class MockBusiness {
@Autowired
private MockService mockService;
public MockOutput businessLogic(MockInput input) {
return mockService.serviceLogic(input);
}
}
MockService
@Service
public class MockService {
@Autowired
private MockUtil mockUtil;
public MockOutput serviceLogic(MockInput input) {
ResponseEntity<MockOutput> res = mockUtil.exchange(UriComponentsBuilder.fromUriString(" "), HttpMethod.GET,
HttpEntity.EMPTY, new ParameterizedTypeReference<MockOutput>() {
});
return res.getBody();
}
}
MockUtil
@Component
public class MockUtil {
@Autowired
private RestTemplate restTemplate;
public <T> ResponseEntity<T> exchange(UriComponentsBuilder uri, HttpMethod method, HttpEntity<?> entity,
ParameterizedTypeReference<T> typeReference) {
try {
ResponseEntity<T> response = restTemplate.exchange(uri.toUriString(), method, entity, typeReference);
return response;
} catch (HttpStatusCodeException ex) {
System.out.println(ex);
return new ResponseEntity<T>(ex.getStatusCode());
} catch (Exception ex) {
ex.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
}
Below is my simple test class, when ever mockUtil.exchange
method is called i want to return object based on ParameterizedTypeReference<T>
MockControllerTest
@SpringBootTest
@ActiveProfiles("test")
@Profile("test")
@RunWith(SpringRunner.class)
public class MockControllerTest {
@Autowired
private MockMainController mockMainController;
@MockBean
private MockUtil mockUtil;
@Test
public void controllerTest() {
given(this.mockUtil.exchange(ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any(),
ArgumentMatchers.any(new ParameterizedTypeReference<MockOutput>() {
}.getClass()))).willReturn(ResponseEntity.ok().body(new MockOutput("hello", "success")));
MockOutput output = mockMainController.mockRequest();
System.out.println(output);
}
}
By debugging I can see that mockUtil.exchange
is returning null
Upvotes: 1
Views: 3212
Reputation: 12205
It seems that the way you match ParameterizedTypeReference
is not working. It does not match as you expect.
Try the following:
given(mockUtil
.exchange(
ArgumentMatchers.any(),
ArgumentMatchers.any(),
ArgumentMatchers.any(),
// eq matches to any param of the same generic type
ArgumentMatchers.eq(new ParameterizedTypeReference<MockOutput>(){})))
.willReturn(ResponseEntity.ok().body(new MockOutput("hello", "success")));
It seems after few tests that if you do not use eq
Mockito expects the passed ParameterizedTypeReference
to be the same instance as in given(..)
and with eq
it just checks that it represents the same generic type.
Check this question for more details.
Upvotes: 3