我是框架新手(刚刚通过了课程),这是我第一次使用 Spring Boot。
我正在尝试运行一个简单的 Junit 测试,以查看我的 CrudRepositories 是否确实有效。
我不断收到的错误是:
无法找到 @SpringBootConfiguration,您需要使用 @ContextConfiguration 或 @SpringBootTest(classes=...) 与您的测试 java.lang.IllegalStateException
Spring Boot 不会自行配置吗?
我的测试班:
@RunWith(SpringRunner.class)
@DataJpaTest
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class JpaTest {
@Autowired
private AccountRepository repository;
@After
public void clearDb(){
repository.deleteAll();
}
@Test
public void createAccount(){
long id = 12;
Account u = new Account(id,"Tim Viz");
repository.save(u);
assertEquals(repository.findOne(id),u);
}
@Test
public void findAccountByUsername(){
long id = 12;
String username = "Tim Viz";
Account u = new Account(id,username);
repository.save(u);
assertEquals(repository.findByUsername(username),u);
}
我的 Spring Boot 应用程序启动器:
@SpringBootApplication
@EnableJpaRepositories(basePackages = {"domain.repositories"})
@ComponentScan(basePackages = {"controllers","domain"})
@EnableWebMvc
@PropertySources(value {@PropertySource("classpath:application.properties")})
@EntityScan(basePackages={"domain"})
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
我的仓库:
public interface AccountRepository extends CrudRepository<Account,Long> {
public Account findByUsername(String username);
}
}
事实上,Spring Boot 确实在很大程度上设置了自己。您可能已经删除了很多您发布的代码,尤其是在 Application
中。
我希望您已包含所有类的包名称,或者至少包含 Application
和 JpaTest
的包名称。关于 @DataJpaTest
和其他一些注解的事情是,它们会在当前包中查找 @SpringBootConfiguration
注解,如果在其中找不到它,则会遍历包层次结构直到找到它。
例如,如果您的测试类的完全限定名称是 com.example.test.JpaTest
,而您的应用程序的名称是 com.example.Application
,那么您的测试类将能够找到 @SpringBootApplication
(其中是 @SpringBootConfiguration
)。
但是,如果应用程序位于包层次结构的不同分支中,例如 com.example.application.Application
,它将不找到它。
例子
考虑以下 Maven 项目:
my-test-project
+--pom.xml
+--src
+--main
+--com
+--example
+--Application.java
+--test
+--com
+--example
+--test
+--JpaTest.java
然后是 Application.java
中的以下内容:
package com.example;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
接下来是JpaTest.java
的内容:
package com.example.test;
@RunWith(SpringRunner.class)
@DataJpaTest
public class JpaTest {
@Test
public void testDummy() {
}
}
一切都应该正常工作。如果您在 src/main/com/example
中创建一个名为 app
的新文件夹,然后将 Application.java
放入其中(并更新文件中的 package
声明),则运行测试会出现以下错误:
java.lang.IllegalStateException:无法找到@SpringBootConfiguration,您需要在测试中使用@ContextConfiguration 或@SpringBootTest(classes=...)
配置附加到应用程序类,因此以下将正确设置所有内容:
@SpringBootTest(classes = Application.class)
JHipster 项目 here 中的示例。
值得检查您是否重构了带有 @SpringBootApplication
注释的主类的包名称。在这种情况下,测试用例应该在适当的包中,否则它将在旧包中寻找它。我就是这种情况。
除了 Thomas Kåsene 说的,还可以添加
@SpringBootTest(classes=com.package.path.class)
如果您不想重构文件层次结构,则添加到测试注释以指定它应该在哪里查找其他类。这就是错误消息所暗示的内容:
找不到@SpringBootConfiguration,需要使用@ContextConfiguration 或@SpringBootTest(classes=...) ...
它对我有用
将上述测试类的包名改为与普通类的包名相同。
https://static.oschina.net/uploads/space/2018/0111/102730_tlKv_2885163.png
改成这个
https://static.oschina.net/uploads/space/2018/0111/103001_vJoi_2885163.png
在我的情况下,应用程序和测试类之间的包是不同的
package com.example.abc;
...
@SpringBootApplication
public class ProducerApplication {
和
package com.example.abc_etc;
...
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerApplicationTest {
在让他们同意后,测试运行正确。
我有同样的问题,我通过在文件夹 src/test/java 的根包中添加一个用 SpringBootApplication
注释的空类来解决
package org.enricogiurin.core;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CoreTestConfiguration {}
Spring Boot 1.4 中提供的测试切片带来了面向特征的测试能力。
例如,
@JsonTest 提供了一个简单的 Jackson 环境来测试 json 序列化和反序列化。
@WebMvcTest 提供了一个 mock 的 web 环境,它可以指定用于测试的控制器类并在测试中注入 MockMvc。
@WebMvcTest(PostController.class)
public class PostControllerMvcTest{
@Inject MockMvc mockMvc;
}
@DataJpaTest 将准备一个嵌入式数据库并为测试提供基本的 JPA 环境。
@RestClientTest 为测试提供 REST 客户端环境,尤其是 RestTemplateBuilder 等。
这些注解不是用 SpringBootTest 组成的,它们是由一系列的 AutoconfigureXXX
和一个 @TypeExcludesFilter
的注解组合而成的。
看看@DataJpaTest
。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(SpringBootTestContextBootstrapper.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(DataJpaTypeExcludeFilter.class)
@Transactional
@AutoConfigureCache
@AutoConfigureDataJpa
@AutoConfigureTestDatabase
@AutoConfigureTestEntityManager
@ImportAutoConfiguration
public @interface DataJpaTest {}
您可以添加 @AutoconfigureXXX 注释以覆盖默认配置。
@AutoConfigureTestDatabase(replace=NONE)
@DataJpaTest
public class TestClass{
}
来看看你的问题
不要混合使用@DataJpaTest 和@SpringBootTest,如上所述,@DataJpaTest 将从应用程序配置继承中以自己的方式构建配置(例如,默认情况下,它将尝试准备嵌入的 H2)。 @DataJpaTest 被指定用于测试切片。如果您想自定义@DataJpaTest 的配置,请阅读 Spring.io 的这篇官方博客文章(有点乏味)。按功能将应用程序中的配置拆分为更小的配置,例如 WebConfig、DataJpaConfig 等。功能齐全的配置(混合 Web、数据、安全等)也会导致基于测试切片的测试失败。检查我的样本中的测试样本。
当所有类都在同一个包中时,测试类正在工作。一旦我将所有 java 类移动到不同的包以维护正确的项目结构,我就会遇到同样的错误。
我通过在下面的测试类中提供我的主类名称来解决它。
@SpringBootTest(classes=JunitBasicsApplication.class)
在我的情况下
确保您的 YourApplicationTests
的 (test package
名称) 与 (main package
名称) 相同。
我认为这个问题的最佳解决方案是将测试文件夹结构与应用程序文件夹结构对齐。
我遇到了同样的问题,这是由于从不同的文件夹结构项目中复制我的项目引起的。
如果您的测试项目和您的应用程序项目将具有相同的结构,您将不需要向您的测试类添加任何特殊注释,并且一切都会按原样工作。
这更多的是错误本身,而不是回答原始问题:
我们正在从 java 8 迁移到 java 11。应用程序编译成功,但是当使用 maven 从命令行运行时,错误 Unable to find a @SpringBootConfiguration
开始出现在集成测试中(从 IntelliJ 运行)。
maven-failsafe-plugin
似乎停止查看类路径上的类,我们通过告诉故障安全插件手动包含这些类来解决这个问题:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>${basedir}/target/classes</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
...
</plugin>
在我的情况下,我使用了错误包中的 Test 类。当我用 import org.junit.jupiter.api.Test;
替换 import org.junit.Test;
时,它起作用了。
确保测试类位于主 Spring Boot 类的子包中
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataJpaTest
@SpringBootTest
@AutoConfigureWebMvc
public class RepoTest {
@Autowired
private ThingShiftDetailsRepository thingShiftDetailsRepo;
@Test
public void findThingShiftDetails() {
ShiftDetails details = new ShiftDetails();
details.setThingId(1);
thingShiftDetailsRepo.save(details);
ShiftDetails dbDetails = thingShiftDetailsRepo.findByThingId(1);
System.out.println(dbDetails);
}
}
以上注释对我来说效果很好。我正在使用带有 JPA 的弹簧靴。
Application
所在的模块。但是,如果您的意思是src/main
和src/test
,那么这些文件夹不是包层次结构的一部分。也许你最好用截图或项目结构的解释来更新你的问题。src/main/java
和src/test/java