Home > Back-end >  springboot Integration test fail when using jsonPath
springboot Integration test fail when using jsonPath

Time:01-18

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.

  • Related