user20112858
user20112858

Reputation: 89

springboot Integration test fail when using jsonPath

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"

Upvotes: 0

Views: 454

Answers (2)

M. Deinum
M. Deinum

Reputation: 124441

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.

Upvotes: 1

Piratformat
Piratformat

Reputation: 1

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"));

Upvotes: 0

Related Questions