Java, 原创,

Spring boot 使用 COLA 框架单元测试常见问题整理

最近在使用Java 的 Spring Boot 搭建单元测试,使用的Cola框架,遇到的几个问题整理如下:

1.运行单元测试时 报错: Failed to determine a suitable driver class

Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class

出现这个问题是因为 单元测试模块下没有单独配置数据库信息。

在 test/resources下创建 application.properties,并加上数据库配置,在哪个模块下测试就需要在哪个模块下建 resources,比如在 gateway,service层测试到请求数据库的, 就需要在gateway,service模块中建resources, 只在infrastructure下放resources是不可以的

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/windigniter
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=root

这样在运行就能正确运行了。

另外如果有外部接口调用 还需要 添加注解

@EnableFeignClients("cn.test.xxx.xxx")

2.运行单元测试报错Failed to retrieve PlatformTransactionManager for @Transactional test

java.lang.IllegalStateException: Failed to retrieve PlatformTransactionManager for @Transactional test
......
contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]

出现这个问题有两种解决方式

第一种解决方法: 如果 mybatis 版本 mybatis-starter.version 使用的 1.3.1等1的版本 就是 缺少 @Transactional注解,添加下面注解

@Transactional(transactionManager = "hibernateTransactionManager")
@TestExecutionListeners({})

第二种解决方式:将mybatis-starter.version版本修改为 2.1.4等2的版本,不需要额外加注解,问题就可解决。

<properties>
	<maven.compiler.target>11</maven.compiler.target>
	<maven.compiler.source>11</maven.compiler.source>
	<mybatis-starter.version>2.1.4</mybatis-starter.version>
</properties>
//导入
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>${mybatis-starter.version}</version>
</dependency>
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter-test</artifactId>
	<version>${mybatis-starter.version}</version>
</dependency>
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-test-autoconfigure</artifactId>
	<version>${mybatis-starter.version}</version>
</dependency>

我们看看 单元测试的 整体代码

package cn.test.fmrs.infrastructure.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringRunner.class)
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Transactional(transactionManager = "hibernateTransactionManager")
@TestExecutionListeners({})
public class BaseTest {
    @Test
    public void test() {
    }
}

当然如果mybatis-starter.version的版本为2.x, 可以去掉 @Transactional 和 @TestExecutionListeners

以上代码是亲自测试过的。

3.调试时报错:NoSuchMethodException BaseSelectProvider init

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method (tk.mybatis.mapper.provider.base.BaseSelectProvider.dynamicSQL).  Cause: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.BaseSelectProvider
...
Error invoking SqlProvider method (tk.mybatis.mapper.provider.base.BaseSelectProvider.dynamicSQL).  Cause: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.BaseSelectProvider
....
Caused by: java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseSelectProvider.<init>()

这个错误也是在 mybatis-starter.version 为 1.x的时候出现的, 将版本修改为 2.x时问题解决

测试启动的类代码如下, AppTest.java

package cn.test.fmrs.infrastructure.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import tk.mybatis.spring.annotation.MapperScan;

@SpringBootApplication
@MapperScan("cn.focusmedia.fmrs.infrastructure.mapper")
@ComponentScan("cn.focusmedia.fmrs")
public class AppTest {
    public static void main(String[] args) {
        SpringApplication.run(AppTest.class, args);
    }
}

(1594)

Related Post