I have worked with the intergration test in springboot and i have tried to test a get method in my controller.The method is work in postman.However it fail in test which the Json path is not found.
The tested controller method:
@GetMapping("/product/{id}")
public Product getproduct(@PathVariable int id){
return productRepository.findById(id).orElse(null);
}
My test code:
@ExtendWith(SpringExtension.class)
@WebMvcTest(OrderController.class)
class OrderControllerTest {
@Autowired
private MockMvc mvc;
@MockBean
private ProductRepository productRepository;
@MockBean
private CustomerRepository customerRepository;
@Test
void getproduct() throws Exception {
/* RequestBuilder request= MockMvcRequestBuilders.;*/
mvc.perform(get("/product/{pid}","201")).andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.productName").value("Mobile"));
}
}
result in postman :
{
"pid": 201,
"productName": "Mobile",
"quantity": 1,
"price": 20000
}
error message:
java.lang.AssertionError: No value at JSON path "$.productName"
CodePudding user response:
As Marko mentions here the jsonPath probably interprets the json body as a list and therefore you can try address the first object in the json body:
.andExpect(jsonPath("$[0].productName").value("Mobile"));
CodePudding user response:
You are using @MockBean
which means you are using mocked repositories not real repositories that are connected to a database. As you have registered no behavior on the mocks it will do its default behavior which is, for Optional
return an empty Optional
. Which results in null
being returned thus no body.
I would suggest to rewrite your controller to the following.
@GetMapping("/product/{id}")
public ResponseEntity<Product> getproduct(@PathVariable int id){
return ResponseEntity.of(productRepository.findById(id));
}
This will probably make your test fail on the assert for OK as it will now return a 404 (NOT FOUND).
To fix your test register same behavior on the mocked repository.
@Test
void getproduct() throws Exception {
Product p = /// Create some product
when(productRepository.findById(201)).thenReturn(Optional.of(p));
mvc.perform(get("/product/{pid}","201")).andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.productName").value("Mobile"));
}
This will create the behavior you want and will return the product, which you can then assert.