wick3d
wick3d

Reputation: 1392

Spring boot controller test returns 200 when expected is 404

I am trying to test the controller layer. In this case to find a customer by id. I have a passing test which works fine and returns 200 status code. Now, I want a failing test case scene. So when I get /customers/1 the test should fail and return a 404, but it is returning 200. Using Junit5, Spring-boot:2.5.3

@WebMvcTest
public class CustomerControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private CustomerService customerService;

    @Test
    @DisplayName("GET /customers/1 -Failure")
    void findCustomerByIdShouldReturn_404() throws Exception {
        when(customerService.findById(1L)).thenReturn(Optional.empty());

        RequestBuilder requestBuilder= MockMvcRequestBuilders.get("/customers/{id}",1);

        mockMvc.perform(requestBuilder)
                .andExpect(status().isNotFound()).andReturn();
    }
}

Error:

      HTTP Method = GET
      Request URI = /customers/1
       Parameters = {}
          Headers = []
             Body = null
    Session Attrs = {}

Handler:
             Type = com.prabhakar.customer.controller.CustomerController
           Method = com.prabhakar.customer.controller.CustomerController#findCustomerById(Long)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = null
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

java.lang.AssertionError: Status expected:<404> but was:<200>
Expected :404
Actual   :200

Here is my controller and service class.

@RestController
public class CustomerController {

    @Autowired
    private CustomerService customerService;

    @GetMapping(path = "/customers/{id}")
    public Optional<Customer> findCustomerById(@PathVariable("id") Long id){
        return customerService.findById(id);
    }
}



@Service
public class CustomerService {
    @Autowired
    private CustomerRepository customerRepository;

    
    public Optional<Customer> findById(Long id) {
        return customerRepository.findById(id);
    }

}

Upvotes: 0

Views: 1637

Answers (1)

Panagiotis Bougioukos
Panagiotis Bougioukos

Reputation: 18909

Your controller does not have the logic that you expect to test. Here is how your controller should be implemented to behave the way you want it to

@RestController
public class CustomerController {

    @Autowired
    private CustomerService customerService;

    @GetMapping(path = "/customers/{id}")
    public ResponseEntity<Customer> findCustomerById(@PathVariable("id") Long id){
        Optional<Customer> optCust = customerService.findById(id);
        if (optCust.isPresent()){
            return ResponseEntity.ok(optCust.get());
        } else {
            return ResponseEntity.notFound().build()
        }
    }
}

Upvotes: 2

Related Questions