Java 错误:在为 Spring Controller 执行 @WebMvcTest 时无法找到 @SpringBootConfiguration

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43515279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:57:37  来源:igfitidea点击:

Error: Unable to find @SpringBootConfiguration when doing @WebMvcTest for Spring Controller

javaspring-mvcspring-bootspring-test

提问by Meena Chaudhary

I am testing my controller given below

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

@Controller
public class MasterController {

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

I am following thisSpring documentation to test my controller. Now, I want to test my controller by just instantiating the web layer and not the whole Spring context as given in the documentation. Below is my code for the same.

我正在按照这个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"));
}

}

When I run this test I get the error Unable to find @SpringBootConfiguration,...etc. But I am confused why it is asking for Spring configuration when we do not want it to instantiate it but want to use only the web layer. Kindly point me to the right direction what is happening here. And also how to fix this. Thanks

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

采纳答案by Meena Chaudhary

So here is the solution:

所以这里是解决方案:

The documentation on detecting test configurationsays:

关于检测测试配置文档说:

The search algorithm works up from the package that contains the test until it finds a @SpringBootApplication or @SpringBootConfiguration annotated class. As long as you've structure your code in a sensible way your main configuration is usually found.

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

So the @SpringBootApplicationclass should be higher in the package hierarchy than the test class e.g if test class is in package com.zerosolutions.controllerthen @SpringBootApplicationclass should be in a package higher than com.zerosolutions.controllerpackage i.e com.zerosolutionsor com.

因此,@SpringBootApplication该类在包层次结构中应该比测试类更高,例如,如果测试类在包中,com.zerosolutions.controller那么@SpringBootApplication类应该在比com.zerosolutions.controller包 iecom.zerosolutionscom.

Problem

问题

But in case the @SpringBootApplicationclass is at the same level as test class it won't be able to find it i.e com.zerosolutions.general. In this case you'll get the following error:

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

java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test

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

Solution

解决方案

If you are running an integrated test, you can explicitly mention the @SpringBootApplicationclass like this

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

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

But if you want to do unit testing of a controller you don't need to fire up the whole Spring context. You can rather replace @SpringBootTestwith @WebMvcTest(MasterController.class). This will instantiate only the web layer with MasterControllerand not the whole Spring context.

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

Problem

问题

But the problem is you will again run into the error we faced earlier:

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

java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test

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

And @WebMvtTestdoes not have a classesattribute like @SpringBootTestto explicitly mention the @SpringBootApplicationclass. So there are two solutions to this.

并且@WebMvtTest没有classes@SpringBootTest明确提及@SpringBootApplication该类的属性。因此,对此有两种解决方案。

Solution

解决方案

First: Move your application class to a package higher than the test class i.e com.zerosolutionsor compackage.

第一:将您的应用程序类移动到比测试类 iecom.zerosolutionscom包更高的包中。

Second: Mention your @SpringBootApplicationclass explicitly like below

第二@SpringBootApplication像下面这样明确提到你的班级

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

Hope that clears the Spring Test Configuration confusion. Thanks

希望能消除 Spring 测试配置的混乱。谢谢

回答by stock

I had the same error, and found that when I had generated the project my pom.xml showed my groupId as com.example rather than with my actual domain:
<groupId>com.example</groupId>
I corrected the pom.xml to be:
<groupId>com.mydomain</groupId>
Next, I changed the file structure from:
src/test/java/com/exampleto src/test/java/com/mydomain
Last, I had to update the package declaration inside my
SampleProjectApplicationTest.java
file to match the correct file structure. Once that was all in place, the tests worked fine.

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

I am not sure how I ended up with com.example where the rest of my project was correct, but the fix was that simple in my case.

我不确定我是如何以 com.example 结束我的项目的其余部分是正确的,但在我的情况下修复就是那么简单。

Hopefully this helps someone.

希望这有助于某人。

回答by Tadele Ayelegn

If your Application.java class (in src/main/java) is located under

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

com.A.B

com.A.B

Your test class ApplicationTest.java (in src/test/java) need to be under

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

com.A.Bor com.A.B.Cor com.A.B.C.D

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

You will get this error if the test class is located under the following packages

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

com.Aor com.A.Cor com.A.D

com.Acom.A.Ccom.A.D

In Spring boot THE GENERAL RULE IS TEST CLASS PACKAGE NAME NEED TO START WITH THE PACKAGE NAME OF THE JAVA CLASS PACKAGE THAT IS GOING TO BE TESTED

在 Spring boot 中,一般规则是测试类包名需要以要测试的 Java 类包的包名开头

回答by Beginner

check if src/test/java has same package name as the main class package. src/test/java/com/example/abc is same as src/test/java/com/example/abc

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