Spring Boot REST控制器测试中@MockitoBean标记对象为null的问题及疑问
Spring Boot REST控制器测试中@MockitoBean标记对象为null的问题及疑问
最近我在尝试测试Spring Boot的REST控制器时遇到了问题,想跟大家请教一下。
问题详情:
我的REST控制器依赖ContactService.java类,所以我用@MockitoBean注解来模拟这个服务类。按照MockMvc设置的相关文档,我写了如下测试代码:
public class ContactRestControllerTest { private MockMvc mockMvc; private ObjectMapper objectMapper; @MockitoBean private ContactService contactService; @BeforeEach void setup() { MockitoAnnotations.openMocks(this); this.objectMapper = new ObjectMapper(); this.mockMvc = MockMvcBuilders .standaloneSetup(new ContactRestController(contactService)) .build(); } @Test void getMessagesByStatus() throws Exception { final String STATUS = "Open"; String messageListStr = "[ { ... } ]"; Page<List<ContactMessage>> pagedContactMessageList = // 此处省略具体实现逻辑 Mockito.when( this.contactService.getContactMessages(Mockito.eq(STATUS), Mockito.anyMap()) ).thenReturn(pagedContactMessageList); mockMvc.perform(...); // 此处省略具体请求逻辑 } }
结果这段代码抛出了空指针异常:
java.lang.NullPointerException: Cannot invoke "...ContactService.getContactMessages(String, java.util.Map)" because "this.contactService" is null at ....ContactRestControllerTest.getMessagesByStatus(ContactRestControllerTest.java:151) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
我的疑问:
明明我已经用@MockitoBean注解标记了contactService,还在setup方法里调用了MockitoAnnotations.openMocks(this);,为什么contactService还是null呢?
后来我试着在测试类上加上@WebMvcTest(ContactRestController.class)注解,测试居然正常运行了!而且这种情况下我甚至不需要调用MockitoAnnotations.openMocks(this),一切都没问题。
如果加@WebMvcTest才是正确的测试方式,那为什么MockMvc设置的文档里会展示另一种写法呢?要怎么做才能让文档里的那种方式生效?我到底漏掉了什么?
Spring Boot版本: 3.4.3
备注:内容来源于stack exchange,提问作者Yousaf
相关产品推荐
相关产品推荐

