Testing MockBean Null

前端 未结 1 982
小蘑菇
小蘑菇 2021-01-14 13:52

I have this class definition

@RestController
public class ReservationController {
    @Autowired
    private Reservation reservation;

    @RequestMapping(val         


        
相关标签:
1条回答
  • 2021-01-14 14:44

    You're getting the error because when you use @MockBean (or @Mock in a non Spring environment) you get a Mockito mock object. This object is a hollow proxy of your object.The proxy has the same public methods as your class and by default return the default value of it's return type (e.g. null for objects, 1 for ints, etc.) or does nothing for void methods.

    Jackson is complaining because it has to serialize this proxy that has no fields and Jackson does not know what to do.

    com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.mockito.internal.debugging.LocationImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS

    In general when you mock a dependency of some class that you want to test, you mock it's public methods, that are used in the class that you test. Directly returning your dependency is not a good real world use case - it's very unlikely that you will have to write a code like this.

    I guess you're trying to learn so let me provide an improved example:

    @RestController
    public class ReservationController {
        @Autowired
        private ReservationService reservationService;     //my chnage here
    
        @RequestMapping(value = "/reservation", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
        @ResponseBody
        public Reservation getReservation() {
    
            return reservationService.getReservation();   //my chnage here
        }
    }
    

    Instead of directly injecting a value object you usually have a service class that contain some business logic and return something - in my example ReservationService which have a method getReservation() that return and object of type Reservation.

    Having that, in your test you can mock the ReservationService.

    @WebMvcTest
    @RunWith(SpringRunner.class)
    public class MvcTest {
        @Autowired
        private MockMvc mockMvc;
    
        @MockBean(name = "reservation")
        private ReservationService reservationService;    //my chnage here
    
        @Test
        public void postReservation() throws Exception {
            // You need that to specify what should your mock return when getReservation() is called. Without it you will get null
            when(reservationService.getReservation()).thenReturn(new Reservation()); //my chnage here
    
            mockMvc.perform(MockMvcRequestBuilders.post("/reservation"))
                    .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
                    .andExpect(MockMvcResultMatchers.status().isOk());
        }
    }
    
    0 讨论(0)
提交回复
热议问题