I have a problem about running the test method named test_When_Order_Success located at OrderServiceImplTest in order service in my spring boot microservice example.
When I run the example after getting a bearer token, I get this issue shown below.
Here is the method shown below.
@DisplayName("Get Order - Success Scenario")
@Test
void test_When_Order_Success() {
String bearerToken = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJVc2VyIiwiaXNzIjoiUk9MRV9VU0VSICIsImlhdCI6MTY3MjQ0Mjg3NywiZXhwIjoxNjcyNDQyOTk3fQ.O6Rm41kFN8SBNUVAiKrsM4O_PBI5qurpmSU34AEk5RTT3ZkPoxiFGeI0byrHOBPPOgyVRXxY_KhgzPcKKgm1ew";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer "+ bearerToken);
HttpEntity request = new HttpEntity<>(headers);
//Mocking
Order order = getMockOrder();
when(orderRepository.findById(anyLong()))
.thenReturn(Optional.of(order));
when(restTemplate.exchange(
"http://PRODUCT-SERVICE/product/" + order.getProductId(),
HttpMethod.GET, request, ProductResponse.class)).thenReturn(ResponseEntity.ok(getMockProductResponse()));
when(restTemplate.exchange(
"http://PAYMENT-SERVICE/payment/order/" + order.getId(),
HttpMethod.GET, request, PaymentResponse.class)).thenReturn(ResponseEntity.ok(getMockPaymentResponse()));
//Actual
OrderResponse orderResponse = orderService.getOrderDetails(1,bearerToken);
//Verification
verify(orderRepository, times(1)).findById(anyLong());
verify(restTemplate, times(1))
.exchange("http://PRODUCT-SERVICE/product/" + order.getProductId(), HttpMethod.GET,
request, ProductResponse.class);
verify(restTemplate, times(1))
.exchange("http://PAYMENT-SERVICE/payment/order/" + order.getId(), HttpMethod.GET,
request, PaymentResponse.class);
//Assert
assertNotNull(orderResponse);
assertEquals(order.getId(), orderResponse.getOrderId());
}
Here is the error message
02:28:15.051 [main] INFO com.microservice.orderservice.service.impl.OrderServiceImpl - OrderServiceImpl | getOrderDetails | Get order details for Order Id : 1
02:28:15.056 [main] INFO com.microservice.orderservice.service.impl.OrderServiceImpl - OrderServiceImpl | getOrderDetails | Invoking Product service to fetch the product for id: 1
org.mockito.exceptions.misusing.PotentialStubbingProblem:
Strict stubbing argument mismatch. Please check:
- this invocation of 'exchange' method:
restTemplate.exchange(
"http://PRODUCT-SERVICE/product/1",
GET,
<[Content-Type:"application/json", Authorization:"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJVc2VyIiwiaXNzIjoiUk9MRV9VU0VSICIsImlhdCI6MTY3MjQ0Mjg3NywiZXhwIjoxNjcyNDQyOTk3fQ.O6Rm41kFN8SBNUVAiKrsM4O_PBI5qurpmSU34AEk5RTT3ZkPoxiFGeI0byrHOBPPOgyVRXxY_KhgzPcKKgm1ew"]>,
class com.microservice.orderservice.payload.response.ProductResponse
);
-> at com.microservice.orderservice.service.impl.OrderServiceImpl.getOrderDetails(OrderServiceImpl.java:113)
- has following stubbing(s) with different arguments:
1. restTemplate.exchange(
"http://PRODUCT-SERVICE/product/1",
GET,
<[Content-Type:"application/json", Authorization:"Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJVc2VyIiwiaXNzIjoiUk9MRV9VU0VSICIsImlhdCI6MTY3MjQ0Mjg3NywiZXhwIjoxNjcyNDQyOTk3fQ.O6Rm41kFN8SBNUVAiKrsM4O_PBI5qurpmSU34AEk5RTT3ZkPoxiFGeI0byrHOBPPOgyVRXxY_KhgzPcKKgm1ew"]>,
class com.microservice.orderservice.payload.response.ProductResponse
);
-> at com.microservice.orderservice.service.OrderServiceImplTest.test_When_Order_Success(OrderServiceImplTest.java:71)
2. restTemplate.exchange(
"http://PAYMENT-SERVICE/payment/order/1",
GET,
<[Content-Type:"application/json", Authorization:"Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJVc2VyIiwiaXNzIjoiUk9MRV9VU0VSICIsImlhdCI6MTY3MjQ0Mjg3NywiZXhwIjoxNjcyNDQyOTk3fQ.O6Rm41kFN8SBNUVAiKrsM4O_PBI5qurpmSU34AEk5RTT3ZkPoxiFGeI0byrHOBPPOgyVRXxY_KhgzPcKKgm1ew"]>,
class com.microservice.orderservice.payload.response.PaymentResponse
);
-> at com.microservice.orderservice.service.OrderServiceImplTest.test_When_Order_Success(OrderServiceImplTest.java:75)
Typically, stubbing argument mismatch indicates user mistake when writing tests.
Mockito fails early so that you can debug potential problem easily.
However, there are legit scenarios when this exception generates false negative signal:
- stubbing the same method multiple times using 'given().will()' or 'when().then()' API
Please use 'will().given()' or 'doReturn().when()' API for stubbing.
- stubbed method is intentionally invoked with different arguments by code under test
Please use default or 'silent' JUnit Rule (equivalent of Strictness.LENIENT).
For more information see javadoc for PotentialStubbingProblem class.
at com.microservice.orderservice.service.impl.OrderServiceImpl.getOrderDetails(OrderServiceImpl.java:113)
at com.microservice.orderservice.service.OrderServiceImplTest.test_When_Order_Success(OrderServiceImplTest.java:94)
How can I fix the issue?
Here is the github repo : Link
To run the app,
1 ) Run Service Registery (Eureka Server)
2 ) Run config server
3 ) Run zipkin and redis through these commands shown below on docker
docker run -d -p 9411:9411 openzipkin/zipkin
docker run -d --name redis -p 6379:6379 redis
4 ) Run api gateway
5 ) Run other services
2
Answers
You only mock
restTemplate
, but notResponseEntity
of any form. So what you basically do:I am even surpised this gives you a NullPointerException, but not a Mockito exception of any kind as you violate the very basics of the mock concept (the object you pass to
when()
is not a mock).In order to make it work pass the RestTemplate mock to
when
, and wrap the desired result into aResponseEntity
to preserve the exchange method return type:First of all, you should use
@ExtendWith(MockitoExtension.class)
instead of@SprintBootTest
on the test class since you are not doing integration test and using JUnit5 with Mockito.Secondly, there is no ‘Bearer ‘ prefix on your Authorization header token in your
OrderServiceImpl
.And you do not need to mock
getBody()
ofResponseEntity
since you already mockrestTemplate.exchange()
.Lastly, the method you are verifying should be
exchange()
notgetForObject()
.