集成测试中 Spring Boot 的数据源自动配置问题

Posted

技术标签:

【中文标题】集成测试中 Spring Boot 的数据源自动配置问题【英文标题】:Spring Boot's datasource auto-configuration issue in Integration tests 【发布时间】:2018-08-04 10:16:29 【问题描述】:

我尝试从application.properties 更改为application.yml。我的 Spring Boot 应用程序启动并且工作正常,但是所有集成测试用例都失败了。

这是控制台日志中的错误消息

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v1.5.10.RELEASE)

***************************
APPLICATION FAILED TO START
***************************

 Description:

Field datasource in com.example.core.config.ServiceConfig 
required a bean of type 'javax.sql.DataSource' that could not be found.

Action:

Consider defining a bean of type 'javax.sql.DataSource' in your configuration.

虽然我在文件 application.yml 中定义了数据源,并且它在运行 Spring boot 应用程序时工作正常......但在运行测试用例时失败,无论是通过 intelliJ runner 还是通过 Gradle -build 任务。

这是我的配置:

spring:
  profiles: default
  datasource:
    hikari:
          minimum-idle: 1
          maximum-pool-size: 5
          pool-name: yourPoolName
          auto-commit: false
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://xxx
    username: xxx
    password: xxx
    maximumPoolSize: 5
    type: com.zaxxer.hikari.HikariDataSource

---
spring:
  profiles: dev
  datasource:
    hikari:
          minimum-idle: 1
          maximum-pool-size: 5
          pool-name: yourPoolName
          auto-commit: false
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://xxx
    username: xx
    password: xx
    maximumPoolSize: 5
    type: com.zaxxer.hikari.HikariDataSource

在我的测试课中,我尝试了所有方法:

@SpringBootTest also 
@ContextConfiguration(classes = ServiceConfig.class, ApplicationConfig.class,initializers = ConfigFileApplicationContextInitializer.class)

似乎没有任何帮助.. 运行测试似乎完全忽略了 aapplication.yml

应用配置

@Configuration
public class ApplicationConfig 

    /**
     *  Total customization - see below for explanation.
     */
    @Autowired
    private Environment environment;

    @PostConstruct
    private void inti () 
       String [] ps =  this.environment.getActiveProfiles();
        for (String p : ps) 

            System.out.println("Currrent profile is "+p);
        
    


    @Autowired
    DataSource datasource;

    @Bean
    public DataSourceTransactionManager transactionManager() throws SQLException 
        return new DataSourceTransactionManager(datasource);
    
    @Bean
    public SqlSessionFactory mySqlSessionFactory() throws Exception 
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(datasource);
        return sessionFactory.getObject();
    

这是我的一个测试类:

@RunWith(SpringRunner.class)
@SpringBootTest(classes =   ApplicationConfig.class)
@ActiveProfiles("dev")
public class OrdersServiceTest 


    @Autowired
    OXUserDetailsService ous;

    @Autowired
    OXOrderServices ors;


    @Before
    public void setup() throws Exception 

    


    @Test
    public void testgetMyOrders() 
        OXUser ou = ous.getUserById(1);

        OXCustomer c = ors.showOrderForUser(ou);
        Assert.assertNotNull(c);
    

    @Test
    public void testgetOrderItemsByOrderId() 
        List<OXOrderItem> ous =ors.getOrderItemsByOrderId(1);
        Assert.assertNotNull(ous);
     

我使用的spring版本是5.0.4及以下是相对启动依赖有:

dependencies 
...
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile group: 'org.hamcrest', name: 'hamcrest-library', version:'1.3'
    testCompile group: 'com.jayway.jsonpath', name: 'json-path', version:'2.2.0'
    testCompile 'org.yaml:snakeyaml:1.19'

我是否缺少一些 Spring Boot 魔术配置?为什么它在测试用例上失败了?

【问题讨论】:

你应该发布文件ApplicationConfig.java的内容。如果测试工作需要另一个基于 Java 的配置文件,让我们发布它的内容。 我不认为 application.config 在这里是相关的,但可以肯定.. 我已经编辑并发布了它...... 能否检查一下,src/main/resources和src/test/resources中的application.yml是否相同? 我在 stc/test/resources 中根本没有 application.yml 文件 【参考方案1】:

(1) 文件application.yml,添加这些行

spring:
  profiles: test
  datasource:
    hikari:
          minimum-idle: 1
          maximum-pool-size: 5
          pool-name: yourPoolName
          auto-commit: false
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://xxx
    username: xxx
    password: xxx
    maximumPoolSize: 5
    type: com.zaxxer.hikari.HikariDataSource

通过删除profiles: test 行,Spring Boot 是自动配置以进行测试。

(2) 文件OrdersServiceTest.java

import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class OrdersServiceTest 

    @Autowired
    OXUserDetailsService ous;

    @Autowired
    OXOrderServices ors;

    @Before
    public void setup() throws Exception 

    

    @Test
    public void testgetMyOrders() 
        OXUser ou = ous.getUserById(1);
        OXCustomer c = ors.showOrderForUser(ou);
        Assert.assertNotNull(c);
    

    @Test
    public void testgetOrderItemsByOrderId() 
        List<OXOrderItem> ous = ors.getOrderItemsByOrderId(1);
        Assert.assertNotNull(ous);
    


参考:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing(支持自动配置测试)

【讨论】:

很遗憾您的建议不起作用。请问还有人吗?【参考方案2】:

yml 文件中可能有多余的空格,

spring:
  profiles: test
  datasource:
    hikari:
          minimum-idle: 1
          maximum-pool-size: 5
          pool-name: yourPoolName
          auto-commit: false

这会起作用吗?

spring:
  profiles: test
  datasource:
    hikari:
      minimum-idle: 1
      maximum-pool-size: 5
      pool-name: yourPoolName
      auto-commit: false

【讨论】:

以上是关于集成测试中 Spring Boot 的数据源自动配置问题的主要内容,如果未能解决你的问题,请参考以下文章

使用内存数据库在 Spring Boot 中进行集成测试

在 Spring Boot 集成测试中使用 TestContainer 填充数据库

spring boot 集成shiro,设置好setLoginUrl后,报404

Spring Boot / Spring数据集成测试

Spring boot 不同数据库环境的集成测试

Spring Boot 测试不会自动装配所有依赖项