Java 执行 JpaTest 时无法找到 @SpringBootConfiguration

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39084491/
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-11 20:52:13  来源:igfitidea点击:

Unable to find a @SpringBootConfiguration when doing a JpaTest

javaspringjunitspring-bootspring-data

提问by Thomas Billet

I'm new to frameworks (just passed the class) and this is my first time using Spring Boot.

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

I'm trying to run a simple Junit test to see if my CrudRepositories are indeed working.

我正在尝试运行一个简单的 Junit 测试,看看我的 CrudRepositories 是否确实在工作。

The error I keep getting is:

我不断收到的错误是:

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

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

Doesn't Spring Boot configure itself?

Spring Boot 不是自己配置的吗?

My Test Class:

我的测试班:

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

 }

My Spring Boot application starter:

我的 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);         

        }
    }

My Repository:

我的存储库:

public interface AccountRepository extends CrudRepository<Account,Long> {

    public Account findByUsername(String username);

    }
}

采纳答案by Thomas K?sene

Indeed, Spring Boot does set itself up for the most part. You can probably already get rid of a lot of the code you posted, especially in Application.

事实上,Spring Boot 确实在很大程度上进行了自我设置。您可能已经摆脱了您发布的很多代码,尤其是在Application.

I wish you had included the package names of all your classes, or at least the ones for Applicationand JpaTest. The thing about @DataJpaTestand a few other annotations is that they look for a @SpringBootConfigurationannotation in the current package, and if they cannot find it there, they traverse the package hierarchy until they find it.

我希望你包括所有的类的包名,或至少药粥ApplicationJpaTest。关于@DataJpaTest和其他一些注解的事情是他们@SpringBootConfiguration在当前包中寻找一个注解,如果他们在那里找不到它,他们就会遍历包层次结构,直到找到它。

For example, if the fully qualified name for your test class was com.example.test.JpaTestand the one for your application was com.example.Application, then your test class would be able to find the @SpringBootApplication(and therein, the @SpringBootConfiguration).

例如,如果您的测试类的完全限定名称是com.example.test.JpaTest,而您的应用程序的完全限定名称是com.example.Application,那么您的测试类将能够找到@SpringBootApplication(以及其中的@SpringBootConfiguration)。

If the application resided in a different branch of the package hierarchy, however, like com.example.application.Application, it would notfind it.

如果应用程序在包层次的不同分支居住,但是,像com.example.application.Application,就不会找到它。

Example

例子

Consider the following Maven project:

考虑以下 Maven 项目:

my-test-project
  +--pom.xml
  +--src
    +--main
      +--com
        +--example
          +--Application.java
    +--test
      +--com
        +--example
          +--test
            +--JpaTest.java

And then the following content in Application.java:

然后是以下内容Application.java

package com.example;

@SpringBootApplication
public class Application {

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

Followed by the contents of JpaTest.java:

其次是内容JpaTest.java

package com.example.test;

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

    @Test
    public void testDummy() {
    }
}

Everything should be working. If you create a new folder inside src/main/com/examplecalled app, and then put your Application.javainside it (and update the packagedeclaration inside the file), running the test will give you the following error:

一切都应该正常工作。如果您创建一个新的文件夹里面src/main/com/exampleapp,然后把你的Application.java里面(和更新package的文件中声明),运行测试会给你以下错误:

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=...)

回答by Cameron Gagnon

In addition to what Thomas K?sene said, you can also add

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

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

to the test annotation to specify where it should look for the other class if you didn't want to refactor your file hierarchy. This is what the error message hints at by saying:

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

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

回答by Mohammed Rafeeq

It is worth to check if you have refactored package name of your main class annotated with @SpringBootApplication. In that case the testcase should be in an appropriate package otherwise it will be looking for it in the older package . this was the case for me.

值得检查您是否重构了主类的包名,并用@SpringBootApplication. 在这种情况下,测试用例应该在一个合适的包中,否则它会在旧包中寻找它。我就是这种情况。

回答by mrts

Configuration is attached to the application class, so the following will set up everything correctly:

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

@SpringBootTest(classes = Application.class)

Example from the JHipster project here.

此处来自 JHipster 项目的示例。

回答by Hantsy

The test sliceprovided in Spring Boot 1.4 brought featureoriented test capabilities.

Spring Boot 1.4 提供的测试切片带来了面向特性的测试能力。

For example,

例如,

@JsonTestprovides a simple Hymanson environment to test the json serialization and deserialization.

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

@WebMvcTestprovides a mock web environment, it can specify the controller class for test and inject the MockMvc in the test.

@WebMvcTest提供了一个 mock 的 web 环境,它可以指定用于测试的控制器类并在测试中注入 MockMvc。

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}

@DataJpaTestwill prepare an embedded database and provides basic JPA environment for the test.

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

@RestClientTestprovides REST client environment for the test, esp the RestTemplateBuilder etc.

@RestClientTest为测试提供 REST 客户端环境,尤其是 RestTemplateBuilder 等。

These annotations are not composed with SpringBootTest, they are combined with a series of AutoconfigureXXXand a @TypeExcludesFilterannotations.

这些注解不是由 SpringBootTest 组成的,它们是由一系列AutoconfigureXXX和一个@TypeExcludesFilter注解组合而成的。

Have a look at @DataJpaTest.

看看@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 {}

You can add your @AutoconfigureXXX annotation to override the default config.

您可以添加 @AutoconfigureXXX 注释来覆盖默认配置。

@AutoConfigureTestDatabase(replace=NONE)
@DataJpaTest
public class TestClass{
}

Let's have a look at your problem,

来看看你的问题

  1. Do not mix @DataJpaTestand @SpringBootTest, as said above @DataJpaTestwill build the configuration in its own way(eg. by default, it will try to prepare an embedded H2 instead) from the application configuration inheritance. @DataJpaTestis designated for test slice.
  2. If you want to customize the configuration of @DataJpaTest, please read this official blog entryfrom Spring.io for this topic,(a little tedious).
  3. Split the configurations in Applicationinto smaller configurations by features, such as WebConfig, DataJpaConfigetc. A full featured configuration(mixed web, data, security etc) also caused your test slicebased tests to be failed. Check the test samplesin my sample.
  1. 不要混合@DataJpaTestand @SpringBootTest,如上所述,@DataJpaTest它将以自己的方式构建配置(例如,默认情况下,它将尝试从应用程序配置继承中准备嵌入的 H2)。@DataJpaTest指定用于测试切片
  2. 如果你想自定义 的配置@DataJpaTest,请阅读Spring.io 这个主题的官方博客条目,(有点乏味)。
  3. 拆分配置在Application成更小的功能配置,如WebConfigDataJpaConfig等。全功能配置(混合网络,数据,安全性等)也引起了您的测试片为基础的测试将失败。检查测试样品我的样本

回答by Umesh G

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

Above annotations worked well for me. I am using spring boot with JPA.

以上注释对我来说效果很好。我正在使用带有 JPA 的弹簧靴。

回答by silver

I think that the best solution for this issue is to align your tests folders structure with the application folder structure.

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

I had the same issue which was caused by duplicating my project from a different folder structure project.

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

if your test project and your application project will have the same structure you will not be required to add any special annotations to your tests classes and everything will work as is.

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

回答by Nick

In my case the packages were different between the Application and Test classes

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

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

and

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

After making them agree the tests ran correctly.

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

回答by hang gao

It work fo me

它对我有用

the package name of the above test class is changed to the same as the package name of the normal class.

上面测试类的包名改成和普通类的包名一样。

change to this

改成这个

回答by SumataPatil

When all the classes were in same package, test classes were working. As soon as I moved all the java classes to different package to maintain proper project structure I was getting the same error.

当所有类都在同一个包中时,测试类就可以工作了。一旦我将所有 java 类移动到不同的包以保持正确的项目结构,我就会遇到同样的错误。

I solved it by providing my main class name in the test class like below.

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

@SpringBootTest(classes=JunitBasicsApplication.class)