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"
1
  • 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). Commented Jan 17, 2023 at 15:10

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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

3 Comments

Unluckly,the same error is still occured: java.lang.AssertionError: No value at JSON path "$[0].productName"
@user20112858 Have you tried adding contentType header to your mock call so the response is a JSON object: mvc.perform(get("/product/{pid}","201").contentType(MediaType.APPLICATION_JSON))
Yes,it also failed sadly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.