最近在使用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);
}
}
(1651)