Java 执行JpaTest时找不到@SpringBootConfiguration

Java 执行JpaTest时找不到@SpringBootConfiguration,java,spring,junit,spring-boot,spring-data,Java,Spring,Junit,Spring Boot,Spring Data,我是框架新手(刚通过课程),这是我第一次使用SpringBoot 我正在尝试运行一个简单的Junit测试,看看我的CrudePositories是否真的有效 我经常遇到的错误是: 无法找到@SpringBootConfiguration,您需要在测试中使用@ContextConfiguration或@SpringBootTest(类=…) java.lang.IllegalStateException SpringBoot不是自己配置的吗 我的测试班: @RunWith(SpringRunner

我是框架新手(刚通过课程),这是我第一次使用SpringBoot

我正在尝试运行一个简单的Junit测试,看看我的CrudePositories是否真的有效

我经常遇到的错误是:

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

SpringBoot不是自己配置的吗

我的测试班:

@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);

    }
}
公共接口AccountRepository扩展了Crudepository{
公共帐户findByUsername(字符串用户名);
}
}

事实上,Spring Boot在大多数情况下都会自行设置。您可能已经可以删除发布的许多代码,尤其是在
应用程序中

我希望您已经包括了所有类的包名,或者至少是
Application
JpaTest
的包名。关于
@DataJpaTest
和其他一些注释,它们在当前包中查找
@SpringBootConfiguration
注释,如果在那里找不到,则遍历包层次结构直到找到它

例如,如果测试类的完全限定名是
com.example.test.JpaTest
,而应用程序的完全限定名是
com.example.application
,那么测试类将能够找到
@springbootcomplication
(其中,
@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);
    }
}
package com.example.test;

@RunWith(SpringRunner.class)
@DataJpaTest
public class JpaTest {

    @Test
    public void testDummy() {
    }
}
然后是
JpaTest.java
的内容:

package com.example;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
package com.example.test;

@RunWith(SpringRunner.class)
@DataJpaTest
public class JpaTest {

    @Test
    public void testDummy() {
    }
}
一切都应该正常。如果在名为
app
src/main/com/example
中创建一个新文件夹,然后将
Application.java
放入其中(并更新文件中的
声明),则运行测试将出现以下错误:

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


除了Thomas Kåsene所说的,您还可以添加

@SpringBootTest(classes=com.package.path.class)
如果您不想重构文件层次结构,请访问测试注释,以指定它应该在何处查找其他类。这就是错误消息的提示,它说:


值得检查的是,您是否重构了用
@SpringBootApplication
注释的主类的包名。在这种情况下,testcase应该在一个合适的包中,否则它将在旧的包中查找它。我就是这样。

配置附加到应用程序类,因此以下内容将正确设置所有内容:

@SpringBootTest(classes = Application.class)

JHipster项目的示例。

Spring Boot 1.4中提供的测试片带来了面向功能的测试功能

比如说,

@JsonTest提供了一个简单的Jackson环境来测试json序列化和反序列化

@WebMvcTest提供了一个模拟web环境,它可以为测试指定控制器类,并在测试中注入MockMvc

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}
@DataJpaTest将准备一个嵌入式数据库,并为测试提供基本的JPA环境

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}
@RestClientTest为测试提供REST客户端环境,特别是RestTemplateBuilder等

这些注释不是由SpringBootTest组成的,它们与一系列
自动配置xx
@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
    @springbootest
    混用,如上所述
    @DataJpaTest
    将以自己的方式从应用程序配置继承中构建配置(例如,默认情况下,它将尝试准备嵌入式H2)
    @DataJpaTest
    是为测试片指定的
  • 如果您想自定义
    @DataJpaTest
    的配置,请阅读Spring.io中的本主题(有点乏味)
  • 应用程序
    中的配置按功能拆分为较小的配置,如
    网络配置
    数据jpaconfig
    等。一个全功能配置(混合网络、数据、安全等)也会导致基于测试片的测试失败。办理登机手续

  • 上面的注释对我很有效。我正在使用JPA的spring boot

    我认为解决这个问题的最佳方法是将测试文件夹结构与应用程序文件夹结构对齐

    我有同样的问题,这是由于从不同的文件夹结构项目复制我的项目造成的


    如果您的测试项目和应用程序项目具有相同的结构,则无需向测试类添加任何特殊注释,所有内容都将按原样工作。

    在我的情况下,应用程序和测试类的包是不同的

    package com.example.abc;
    ...
    @SpringBootApplication
    public class ProducerApplication {
    

    让他们同意后,测试运行正常。

    对我来说很有效

    上述测试类的包名更改为与普通类的包名相同

    换成这个


    当所有类都在同一个包中时,测试类正在工作。当我将所有java类移到不同的包中以维护适当的项目结构时
    @SpringBootTest(classes=JunitBasicsApplication.class)
    
    package org.enricogiurin.core;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class CoreTestConfiguration {}
    
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <configuration>
                    <additionalClasspathElements>
                        <additionalClasspathElement>${basedir}/target/classes</additionalClasspathElement>
                    </additionalClasspathElements>
                </configuration>
                ...
            </plugin>