错误:在为 Spring Controller 执行 @WebMvcTest 时找不到 @SpringBootConfiguration

Posted

技术标签:

【中文标题】错误:在为 Spring Controller 执行 @WebMvcTest 时找不到 @SpringBootConfiguration【英文标题】:Error: Unable to find @SpringBootConfiguration when doing @WebMvcTest for Spring Controller 【发布时间】:2017-09-16 20:05:31 【问题描述】:

我正在测试下面给出的控制器

@Controller
public class MasterController 

@GetMapping("/")
public String goLoginPage()
    return "index";


我正在关注this Spring 文档来测试我的控制器。 现在,我想通过仅实例化 Web 层而不是文档中给出的整个 Spring 上下文来测试我的控制器。下面是我的代码。

@RunWith(SpringRunner.class)
@WebMvcTest
public class MasterControllerTestWithWebLayer 

@Autowired
MockMvc mockMvc;

@Autowired
MasterController masterController;


@Before
public void setUp() throws Exception 


@After
public void tearDown() throws Exception 


@Test
public void testLoginHome() throws Exception
    mockMvc.perform(get("/"))
    .andExpect(status().isOk())
    .andExpect(view().name("index"));



当我运行这个测试时,我得到了错误Unable to find @SpringBootConfiguration,...etc。但我很困惑为什么当我们不希望它实例化它但只想使用 web 层时它要求 Spring 配置。请指出这里发生的事情的正确方向。以及如何解决这个问题。谢谢

【问题讨论】:

试试这个@WebMvcTest(controllers = MasterController.class)。并删除这个@Autowired MasterController masterController; @pvpkiran 好吧,那行得通,但为什么不这样呢? 您的控制器中是否还有其他依赖项。例如像一个服务类什么的? @pvpkiran 不,猜猜即使我在@WebMvcTest 中给出控制器名称,它仍然无法正常工作? 尝试将 @SpringBootTest(classes = YourSpringBootClassName.class) 放在 MasterControllerTestWithWebLayer 类之上 【参考方案1】:

所以这里是解决方案:

documentation on detecting test configuration 说:

搜索算法从包含测试的包开始,直到找到@SpringBootApplication 或@SpringBootConfiguration 注释类。只要您以合理的方式构建代码,通常就能找到您的主要配置。

所以@SpringBootApplication 类在包层次结构中应该比测试类更高,例如,如果测试类在包com.zerosolutions.controller 中,那么@SpringBootApplication 类应该在高于com.zerosolutions.controller 包的包中,即com.zerosolutionscom

问题

但如果@SpringBootApplication 类与测试类处于同一级别,它将无法找到它,即com.zerosolutions.general。在这种情况下,您将收到以下错误:

java.lang.IllegalStateException: 找不到@SpringBootConfiguration,您需要在测试中使用@ContextConfiguration 或@SpringBootTest(classes=...)

解决方案

如果您正在运行集成测试,则可以像这样明确提及 @SpringBootApplication

@RunWith(SpringRunner.class)
@SpringBootTest(classes=SpringBootApp.class)

但是如果你想对控制器进行单元测试,你不需要启动整个 Spring 上下文。您可以将@SpringBootTest 替换为@WebMvcTest(MasterController.class)。这将仅使用 MasterController 实例化 Web 层,而不是整个 Spring 上下文。

问题

但问题是你会再次遇到我们之前遇到的错误:

java.lang.IllegalStateException: 找不到@SpringBootConfiguration,您需要在测试中使用@ContextConfiguration 或@SpringBootTest(classes=...)

并且@WebMvtTest 没有像@SpringBootTest 这样的classes 属性来明确提及@SpringBootApplication 类。 所以有两种解决方案。

解决方案

首先:将您的应用程序类移动到高于测试类的包,即com.zerosolutionscom 包。

第二个:如下所示明确提及您的@SpringBootApplication

@RunWith(SpringRunner.class)
@WebMvcTest(MasterController.class)
@ContextConfiguration(classes=SpringBootApp.class)

希望能消除 Spring 测试配置的困惑。谢谢

【讨论】:

您的回答帮助我找出了我花了数小时解决的问题。测试类无法找到主引导应用程序类,尽管它似乎在同一个包下但在主文件夹和测试文件夹中。一旦我使用注释 @SpringBootTest(classes=...) 明确指出主应用程序类,事情就开始工作了。 这对我有帮助。就我而言,我的测试是放置在没有任何 package 声明的文件中的 Kotlin 类。它是由于一些复制粘贴和移动东西而发生的。 Intellij 的 Kotlin 插件从未警告过我放错类。 很好的答案帮助我理解了问题和解决方案! 完美解释!【参考方案2】:

如果您的 Application.java 类(在 src/main/java 中)位于

com.A.B

你的测试类ApplicationTest.java(在src/test/java中)需要在

com.A.Bcom.A.B.Ccom.A.B.C.D

如果测试类位于以下包下,您将收到此错误

com.Acom.A.Ccom.A.D

在春季启动 一般规则是测试类包名需要以要测试的JAVA类包的包名开头

【讨论】:

在我的项目中,我的 Application.class 位于 src/main/java/com/company/example 中,我的测试类 ApplicationTest.java 位于 src/test/java/com/company/example .测试执行(mvn test)仍然抛出 IllegalStateException。我从你的解释中误解了什么吗?我认为spring boot能够通过这个设置自动找到应用程序类。 是的 Spring Boot 测试类应该和主类在同一个包中。【参考方案3】:

我遇到了同样的错误,发现当我生成项目时,我的 pom.xml 将我的 groupId 显示为 com.example 而不是我的实际域:<groupId>com.example</groupId> 我将 pom.xml 更正为:<groupId>com.mydomain</groupId> 接下来,我将文件结构从:src/test/java/com/example更改为src/test/java/com/mydomain 最后,我必须更新 mySampleProjectApplicationTest.java 中的包声明 文件以匹配正确的文件结构。一切就绪后,测试工作正常。

我不确定我是如何以 com.example 结束的,我的项目的其余部分是正确的,但就我而言,修复就是这么简单。

希望这对某人有所帮助。

【讨论】:

【参考方案4】:

检查 src/test/java 是否与主类包有相同的包名。 src/test/java/com/example/abc 和 src/test/java/com/example/abc 一样

【讨论】:

【参考方案5】:

只需将测试包名称替换为主应用程序类包名称即可。

示例:- package com.kotlin.dealerMainApplication 这是我的主应用程序包名称,所以我将在我的测试包中放入相同的名称

这对我有用!

【讨论】:

以上是关于错误:在为 Spring Controller 执行 @WebMvcTest 时找不到 @SpringBootConfiguration的主要内容,如果未能解决你的问题,请参考以下文章

Spring Controller:对象='invoiceData' 的验证失败。错误数:4

whitelabel 错误页面 404 spring boot 微服务 Rest Controller

Spring Boot Rest Controller:返回默认错误 JSON

spring的全局自定义异常案例「完美拦截Controller层全部异常」

Spring Boot中Controller的统一异常处理

Spring MVC Controller异常处理总结