Spring Boot MVC 测试 - MockMvc 始终为空
Posted
技术标签:
【中文标题】Spring Boot MVC 测试 - MockMvc 始终为空【英文标题】:Spring Boot MVC Test - MockMvc is always null 【发布时间】:2020-04-19 09:37:48 【问题描述】:我正在尝试编写我的第一个 Spring MVC 测试,但我无法让 Spring Boot 将 MockMvc 依赖项注入我的测试类。这是我的课:
@WebMvcTest
public class WhyWontThisWorkTest
private static final String myUri = "uri";
private static final String jsonFileName = "myRequestBody.json";
@Autowired
private MockMvc mockMvc;
@Test
public void iMustBeMissingSomething() throws Exception
byte[] jsonFile = Files.readAllBytes(Paths.get("src/test/resources/" + jsonFileName));
mockMvc.perform(
MockMvcRequestBuilders.post(myUri)
.content(jsonFile)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().is2xxSuccessful());
我检查过 IntelliJ 的调试器,可以确认 mockMvc 本身为空。因此,所有异常消息告诉我的是“java.lang.NullPointerException”。
我已经尝试为“@SpringBootTest”或“@RunWith(SpringRunner.class)”等测试类添加更通用的 Spring Boot 注释,以防它与初始化 Spring 有关但没有运气。
【问题讨论】:
你能提供你的 pom 或 gradle 文件吗? 【参考方案1】:奇怪,前提是你也尝试过 @RunWith(SpringRunner.class)
和 @SpringBootTest
。您是否也尝试过 @AutoConfigureMockMvc
注释?下面的示例运行良好。
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTest
@Autowired
private MockMvc mockMvc;
@Test
public void getHello() throws Exception
mockMvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(equalTo("Hello World of Spring Boot")));
完整示例here
关于@WebMvcTest 和@AutoConfigureMockMvc 注释的使用,可能还值得考虑以下cmets,详见Spring's documentation
默认情况下,使用 @WebMvcTest 注解的测试也会自动配置 Spring Security 和 MockMvc(包括对 htmlUnit WebClient 和 Selenium WebDriver 的支持)。要对 MockMVC 进行更细粒度的控制,可以使用 @AutoConfigureMockMvc 注解。
通常@WebMvcTest 与@MockBean 或@Import 结合使用以创建@Controller bean 所需的任何协作者。
如果您希望加载完整的应用程序配置并使用 MockMVC,则应考虑将 @SpringBootTest 与 @AutoConfigureMockMvc 结合使用,而不是使用此注解。
使用 JUnit 4 时,此注解应与 @RunWith(SpringRunner.class) 结合使用。
【讨论】:
@ElDuderino,很高兴它做到了。编码愉快! 非常感谢,这成功了,让我通过了 NullPointerException。我现在使用这些注释: @RunWith(SpringRunner.class) @SpringBootTest(classes = MyApplication.class) @AutoConfigureMockMvc @PropertySource("classpath:application.properties") 不幸的是,测试现在卡在 Spring-logo 上。当我运行应用程序并手动发布我的文件时,它工作正常。可能需要补充一点,这个测试基本上覆盖了应用的每一层,所以Spring Boot需要初始化几乎整个应用才能运行测试。 好的,不知道你的 byte[] 内容是否与 MediaType.APPLICATION_JSON 兼容?您可以将 json 文件内容(作为纯文本)放在一个字符串中并将其用作内容而不是您的 byte[]...如果它通过了卡住,那么我们知道它是否是格式问题 不是这样,我忘了声明要与@ActiveProfiles 一起使用的配置文件(我有多个application.properties)。现在它开始了。感谢您的帮助,由于原始问题现已解决,因此我将您的答案标记为已接受。 @ElDuderino 完美。很高兴一切都解决了。编码快乐,2020 年新年快乐【参考方案2】:我遇到了同样的问题。原来MockMvc
没有被注入是因为不兼容的@Test
注解。导入的是 org.junit.Test
,但将其更改为 org.junit.jupiter.api.Test
解决了问题。
【讨论】:
【参考方案3】:接受的答案有效,但我也解决了这个问题,但没有导入 @RunWith(SpringRunner.class)
。
在我的例子中,我导入了 org.junit.Test
而不是更新的 org.junit.jupiter.api.Test
。
如果您使用的是 Maven,则可以避免犯此错误,从 spring-boot-starter-test
依赖项中排除 junit-vintage-engine
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
【讨论】:
以上是关于Spring Boot MVC 测试 - MockMvc 始终为空的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Junit5 / spring boot 中命令执行控制器测试类?