gpt4 book ai didi

spring - 测试 MockBean 为空

转载 作者:行者123 更新时间:2023-11-28 20:36:06 27 4
gpt4 key购买 nike

我有这个类定义

@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;
}
}

Reservation 是一个简单的 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 + "]";
}
}

当我尝试测试这个类时

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

我遇到了这个错误:

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

如何以正确的方式注入(inject)预订?

谢谢

最佳答案

您收到错误是因为当您使用 @MockBean(或在非 Spring 环境中使用 @Mock)时,您会得到一个 Mockito 模拟对象。该对象是您对象的空心代理。该代理具有与您的类相同的公共(public)方法,并且默认返回其返回类型的默认值(例如,对象为 null,整数为 1 等),或者对 void 方法不执行任何操作.

Jackson 在提示,因为它必须序列化这个没有字段的代理,而 Jackson 不知道该怎么做。

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

通常,当您模拟某个要测试的类的依赖项时,您模拟的是它的公共(public)方法,这些方法在您测试的类中使用。直接返回你的依赖不是一个很好的现实世界用例——你不太可能必须编写这样的代码。

我猜你正在努力学习,所以让我提供一个改进的例子:

@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
}
}

不是直接注入(inject)一个值对象,你通常有一个包含一些业务逻辑并返回一些东西的服务类 - 在我的示例 ReservationService 中,它有一个方法 getReservation()返回 Reservation 类型的对象。

有了它,在您的测试中您可以模拟 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());
}
}

关于spring - 测试 MockBean 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53780625/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com