在执行JpaTest时无法找到@SpringBootConfiguration

Tho*_*let 160 java junit spring spring-data spring-boot

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

我正在尝试运行一个简单的Junit测试来查看我的CrudRepositories是否确实正常工作.

我一直得到的错误是:

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

不弹簧启动配置自己?

我的测试班

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

 }
Run Code Online (Sandbox Code Playgroud)

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

        }
    }
Run Code Online (Sandbox Code Playgroud)

我的存储库

public interface AccountRepository extends CrudRepository<Account,Long> {

    public Account findByUsername(String username);

    }
}
Run Code Online (Sandbox Code Playgroud)

提前致谢

Tho*_*ene 231

实际上,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
Run Code Online (Sandbox Code Playgroud)

然后是以下内容Application.java:

package com.example;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

其次是JpaTest.java:

package com.example.test;

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

    @Test
    public void testDummy() {
    }
}
Run Code Online (Sandbox Code Playgroud)

一切都应该有效.如果在src/main/com/example被调用的内部创建一个新文件夹app,然后将其Application.java放入其中(并package在文件中更新声明),运行测试将给出以下错误:

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

  • +-测试+-com +-示例+-JpaTest.java也可以 (2认同)

mrt*_*rts 87

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

@SpringBootTest(classes = Application.class)
Run Code Online (Sandbox Code Playgroud)

这里的JHipster项目示例.

  • 这太完美了!更准确地说,这解决了 Thomas 在他的帖子中提出的问题_如果应用程序驻留在包层次结构的不同分支中,但是,如 com.example.application.Application,它将找不到它。_。 (2认同)

Moh*_*eeq 19

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


han*_*gao 11

它对我有用

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

改成这个


小智 9

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

package com.example.abc;
...
@SpringBootApplication
public class ProducerApplication {
Run Code Online (Sandbox Code Playgroud)

package com.example.abc_etc;
...
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerApplicationTest {
Run Code Online (Sandbox Code Playgroud)

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


Cam*_*non 8

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

@SpringBootTest(classes=com.package.path.class)
Run Code Online (Sandbox Code Playgroud)

如果您不想重构文件层次结构,请在测试注释中指定它应该查找其他类的位置.这是错误消息提示的内容:

Unable to find a @SpringBootConfiguration, you need to use 
@ContextConfiguration or @SpringBootTest(classes=...) ...
Run Code Online (Sandbox Code Playgroud)


Enr*_*rin 8

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

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

@SpringBootApplication
public class CoreTestConfiguration {}
Run Code Online (Sandbox Code Playgroud)


Han*_*tsy 7

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

例如,

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

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

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}
Run Code Online (Sandbox Code Playgroud)

@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 {}
Run Code Online (Sandbox Code Playgroud)

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

@AutoConfigureTestDatabase(replace=NONE)
@DataJpaTest
public class TestClass{
}
Run Code Online (Sandbox Code Playgroud)

我们来看看你的问题

  1. 不要混合@DataJpaTest@SpringBootTest,如上所述,@DataJpaTest它将以自己的方式从应用程序配置继承构建配置(例如,默认情况下,它将尝试准备嵌入式 H2)。@DataJpaTest指定用于测试切片
  2. 如果你想自定义配置@DataJpaTest,请阅读Spring.io 的这篇官方博客文章(有点繁琐)。
  3. Application按功能将配置拆分为更小的配置,例如等WebConfig全功能配置(混合 Web、数据、安全性等)也会导致基于测试切片的测试失败。检查我的样本中的 测试样本DataJpaConfig