执行JpaTest时找不到@SpringBootConfiguration


184

我是框架的新手(刚刚通过该类),这是我第一次使用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);

    }
}

Answers:


264

确实,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名为中创建一个新文件夹app,然后将其Application.java放入其中(并更新package文件中的声明),则运行测试将给您以下错误:

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


1
问候,感谢您提供使用Maven数据包设置提供解决方案的解决方案,其中包含用于测试和应用程序代码的其他程序包。如果我正确理解您的意思,那我必须将测试包定向到Application类吗?然后它将找到SpringConfiguration?
托马斯·比利

如果用“行包”表示“模块”,那么是的,测试类所在的模块必须依赖于其中的模块Application。但是,如果用src/main和表示src/test,则这些文件夹不属于包的一部分。层次结构。也许最好用屏幕快照或项目结构的说明来更新问题。
ThomasKåsene'16

正如您所说,我刚刚解决了这个问题。经过一番谷歌搜索后,我发现了建议的弹簧包结构并将其全部重构。现在测试按预期运行。非常感谢
Thomas Billet

好了,很高兴知道!无论如何,我用更详尽的示例更新了答案。
ThomasKåsene'16

3
+-测试+-com +-示例+-JpaTest.java也可以使用
user674158

104

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

@SpringBootTest(classes = Application.class)

这里的JHipster项目示例。


这似乎是完美的解决方案。我不需要移动任何班级或文件夹。
Abhishek Aggarwal

21

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


11

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

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

到测试注释,以指定如果您不想重构文件层次结构,应该在哪里寻找其他类。这是错误消息通过提示所暗示的内容:

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

这是一个非常有价值的答案!谢谢@cameron!
兰斯(Lance Kind)

5

就我而言,应用程序类和测试类之间的包是不同的

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

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

让他们同意后,测试才能正确运行。


5

它对我有用

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

换成这个


3

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上有关此主题的官方博客条目(有点乏味)。
  3. Application按功能将配置拆分为较小的配置,例如WebConfigDataJpaConfig全功能配置(混合的Web,数据,安全性等)也会导致基于测试切片的测试失败。检查测试样品我的样本

1

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

我有一个相同的问题,该问题是由于从另一个文件夹结构项目中复制我的项目而引起的。

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


我遇到了同样的错误,最后我发现测试类的程序包名称有一个错字“ rule”而不是“ rules”。固定软件包名称后,错误消失了。
Gopal Bairwa,

1

当所有类都放在同一个程序包中时,测试类就可以正常工作。一旦我将所有java类都移到了不同​​的程序包以维护正确的项目结构,我就得到了相同的错误。

我通过在测试类中提供我的主类名称来解决它,如下所示。

@SpringBootTest(classes=JunitBasicsApplication.class)

1

我遇到了同样的问题,我通过SpringBootApplication在文件夹src / test / java的根包中添加带注释的空类来解决

package org.enricogiurin.core;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CoreTestConfiguration {}

0

在我的情况下
确保你的(test package名字)的YourApplicationTests相当于(main package名称)。


-2
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。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.