0

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"
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
user20112858
  • 79
  • 1
  • 6
  • 1
    You are using mocks and I see no where behavior being registered for the mocked repositories. No mocking, no result (or at least an empty result). – M. Deinum Jan 17 '23 at 15:10

2 Answers2

1

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.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
0

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