mock如何为空,测试MockBean为空

I have this class definition

@RestController

public class ReservationController {

@Autowired

private Reservation reservation;

@RequestMapping(value = "/reservation", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)

@ResponseBody

public Reservation getReservation() {

return reservation;

}

}

where Reservation is a simple Pojo

public class Reservation {

private long id;

private String reservationName;

public Reservation() {

super();

this.id = 333;

this.reservationName = "prova123";

}

public Reservation(long id, String reservationName) {

super();

this.id = id;

this.reservationName = reservationName;

}

public long getId() {

return id;

}

public void setId(long id) {

this.id = id;

}

public String getReservationName() {

return reservationName;

}

public void setReservationName(String reservationName) {

this.reservationName = reservationName;

}

@Override

public String toString() {

return "Reservation [id=" + id + ", reservationName=" + reservationName + "]";

}

}

when I try to test this class

@WebMvcTest

@RunWith(SpringRunner.class)

public class MvcTest {

@Autowired

private MockMvc mockMvc;

@MockBean(name = "reservation")

private Reservation reservation;

@Test

public void postReservation() throws Exception {

mockMvc.perform(MockMvcRequestBuilders.post("/reservation"))

.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))

.andExpect(MockMvcResultMatchers.status().isOk());

}

}

I got this error:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.mockito.internal.debugging.LocationImpl]; nested exception is 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) (through reference chain: spring.boot.usingSpringBoot.entity.Reservation$MockitoMock$980801978["mockitoInterceptor"]->org.mockito.internal.creation.bytebuddy.MockMethodInterceptor["mockHandler"]->org.mockito.internal.handler.InvocationNotifierHandler["invocationContainer"]->org.mockito.internal.stubbing.InvocationContainerImpl["invocationForStubbing"]->org.mockito.internal.invocation.InvocationMatcher["invocation"]->org.mockito.internal.invocation.InterceptedInvocation["location"])

....

....

Caused by: 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) (through reference chain: spring.boot.usingSpringBoot.entity.Reservation$MockitoMock$980801978["mockitoInterceptor"]->org.mockito.internal.creation.bytebuddy.MockMethodInterceptor["mockHandler"]->org.mockito.internal.handler.InvocationNotifierHandler["invocationContainer"]->org.mockito.internal.stubbing.InvocationContainerImpl["invocationForStubbing"]->org.mockito.internal.invocation.InvocationMatcher["invocation"]->org.mockito.internal.invocation.InterceptedInvocation["location"])

How can I inject reservation in the right way??

Thank you

解决方案

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

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值