在执行JpaTest时无法找到@SpringBootConfiguration

时间:2016-08-22 16:30:02

标签: java spring junit spring-boot spring-data

我是框架的新手(刚刚通过了这个课程),这是我第一次使用springboot。

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

我不断得到的错误是:

  

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

没有弹簧启动配置自己?

我的测试班

@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启动应用程序启动器

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

    }
}

提前致谢

15 个答案:

答案 0 :(得分:200)

事实上,Spring Boot确实在很大程度上确立了自己的地位。你可能已经摆脱了很多你发布的代码,特别是在Application

我希望您已包含所有类的包名,或至少包含ApplicationJpaTest的包名。关于@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的{​​{1}}内创建一个新文件夹,然后将app放入其中(并在文件中更新Application.java声明),则运行测试将给出你有以下错误:

  

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

答案 1 :(得分:70)

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

@SpringBootTest(classes = Application.class)

JHipster项目here的示例。

答案 2 :(得分:15)

值得检查您是否已使用@SpringBootApplication注释的主类的重构包名称。在这种情况下,测试用例应该在适当的包装中,否则它将在较旧的包装中寻找它。这就是我的情况。

答案 3 :(得分:8)

除了ThomasKåsene所说的,你还可以添加

@SpringBootTest(classes=com.package.path.class)

指向测试注释,以指定在不想重构文件层次结构时应该查找其他类的位置。这是错误消息提示的内容:

Unable to find a @SpringBootConfiguration, you need to use 
@ContextConfiguration or @SpringBootTest(classes=...) ...

答案 4 :(得分:2)

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

例如,

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

@WebMvcTest 提供了一个模拟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{
}

让我们来看看你的问题,

  1. 不要混用@DataJpaTest@SpringBootTest,如上所述@DataJpaTest将以自己的方式构建配置(例如,默认情况下,它会尝试准备嵌入式H2)从应用程序配置继承。 @DataJpaTest指定用于测试切片
  2. 如果您想自定义@DataJpaTest的配置,请阅读Spring.io的this official blog entry以了解此主题,(有点单调乏味)。
  3. 按照ApplicationWebConfig等功能将DataJpaConfig中的配置拆分为较小的配置。全功能配置(混合网络,数据,安全性等)也导致基于测试切片的测试失败。查看test samples中的my sample

答案 5 :(得分:1)

它对我有用

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

更改为此

答案 6 :(得分:1)

就我而言
确保您test package的( YourApplicationTests名称)与( main package名称)等效。

答案 7 :(得分:1)

我遇到了同样的问题,我通过在文件夹 src / test / java

的根包中添加一个用SpringBootApplication注释的空类来解决
package org.enricogiurin.core;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CoreTestConfiguration {}

答案 8 :(得分:0)

我认为针对此问题的最佳解决方案是使测试文件夹结构与应用程序文件夹结构对齐。

我遇到了相同的问题,该问题是由于从不同的文件夹结构项目复制项目而导致的。

如果您的测试项目和应用程序项目具有相同的结构,则无需为测试类添加任何特殊注释,一切都将照常进行。

答案 9 :(得分:0)

在我的情况下,Application和Test类之间的包不同

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

package com.example.abc_etc;
...
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerApplicationTest {

在让他们同意测试正确运行之后。

答案 10 :(得分:0)

当所有类都在同一个程序包中时,测试类正在运行。一旦我将所有Java类都移到了不同​​的程序包以维护正确的项目结构,我就会遇到相同的错误。

我通过在下面的测试类中提供主类名称来解决。

@SpringBootTest(classes = JunitBasicsApplication.class)

希望这会有所帮助!!

答案 11 :(得分:0)

在我的情况下,我使用错误的程序包中的Test类。 当我将import org.junit.Test;替换为导入org.junit.jupiter.api.Test;时,它起作用了。

答案 12 :(得分:0)

确保测试类位于主spring boot类的子包中

答案 13 :(得分:0)

更多的是错误本身,没有回答原始问题:

我们正在从Java 8迁移到Java11。成功编译了应用程序,但是当使用maven从命令行运行时,错误Unable to find a @SpringBootConfiguration开始出现在集成测试中(从IntelliJ运行)。

maven-failsafe-plugin似乎不再看到类路径上的类,我们通过告诉failsafe插件手动包括这些类来解决该问题:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <configuration>
                <additionalClasspathElements>
                    <additionalClasspathElement>${basedir}/target/classes</additionalClasspathElement>
                </additionalClasspathElements>
            </configuration>
            ...
        </plugin>

答案 14 :(得分:-1)

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中使用spring boot。