springboot集成spock,groovy单元测试框架
·
单元测试最好不依赖实际的数据库,在任何环境都可以跑。本文使用h2内存数据库,liquibase初始化测试数据,embedded-redis内存redis等来摆脱环境依赖。
1.技术框架和环境
springboot,idea,maven,liquibase,h2,spock,embedded-redis,mybatis-plus等。
2.工程结构

3. pom.xml配置
<properties>
<liquibase.version>3.8.9</liquibase.version>
<h2.version>1.4.197</h2.version>
<groovy.version>2.5.14</groovy.version>
<spock.version>1.3-groovy-2.5</spock.version>
<cglib-nodep.version>2.2</cglib-nodep.version>
<junit-platform-launcher>1.7.1</junit-platform-launcher>
<embedded-redis>0.7.3</embedded-redis>
</properties>
<dependencies>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>${liquibase.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>${groovy.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>${spock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<version>${spock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib-nodep.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>embedded-redis</artifactId>
<version>${embedded-redis}</version>
<scope>test</scope>
</dependency>
</dependencies>
4. application-test.yml配置
server:
port: 8000
servlet:
context-path: /code_proxy
spring:
profiles:
active: test
application:
name: freedom-code
datasource:
type: com.alibaba.druid.pool.DruidDataSource
# MYSQL 5 驱动:com.mysql.jdbc.Driver,MYSQL 6+ 驱动:com.mysql.cj.jdbc.Driver
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:mybatisplus;MODE=Mysql;DB_CLOSE_DELAY=1;TRACE_LEVEL_SYSTEM_OUT=2;
username: root
password: root
druid:
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 100
# 配置获取连接等待超时的时间
max-wait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存时间
min-evictable-idle-time-millis: 300000
validation-query: select VERSION()
test-while-idle: true
test-on-borrow: false
test-on-return: false
liquibase:
change-log: 'classpath:/db/changelog/db.mysql-mater.xml'
database-change-log-lock-table: databasechangeloglock
database-change-log-table: databasechangelog
drop-first: false
enabled: true
test-rollback-on-update: false
h2:
console:
enabled: true
path: /h2-console
redis:
database: 2
host: localhost
lettuce:
pool:
max-active: 16
max-idle: 8
max-wait: 4000
min-idle: 6
port: 6379
timeout: 4000
# mybatisplus的配置
mybatis-plus:
configuration:
# 是否开启自动驼峰命名规则
map-underscore-to-camel-case: true
# 对所有的 resultMap 都进行自动映射
auto-mapping-behavior: full
# #控制台打印完整带参数SQL语句
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:mapper/**/*.xml
# ===== 自定义swagger配置 ===== #
swagger:
enable: true
application-name: ${spring.application.name}
application-version: 1.0
application-description: springfox swagger 3.0 demo
try-host: http://localhost:${server.port}
test:
conditional:
enabled: true
5. liquibase配置
spring:
liquibase:
change-log: 'classpath:/db/changelog/db.mysql-mater.xml'
database-change-log-lock-table: databasechangeloglock
database-change-log-table: databasechangelog
drop-first: false
enabled: true
test-rollback-on-update: false


6. 关键代码配置
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootTest(classes = FreedomApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
@Stepwise
public @interface CodeBootTest {
}
@ConditionalOnProperty(prefix = "test.conditional", name = "enabled", havingValue = "true")
@Configuration
@EnableRedisRepositories
public class TestRedisConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory(RedisProperties redisProperties) {
return new LettuceConnectionFactory(redisProperties.getHost(), redisProperties.getPort());
}
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
return template;
}
}
@ConditionalOnProperty(prefix = "test.conditional", name = "enabled", havingValue = "true")
@Configuration
public class TestRedisServiceConfig {
private RedisServer redisServer;
public TestRedisServiceConfig(RedisProperties redisProperties) {
// this.redisServer = new RedisServer(redisProperties.getPort());
this.redisServer = RedisServer.builder().port(redisProperties.getPort()).setting("maxmemory 128M").build();
}
@PostConstruct
public void postConstruct() {
redisServer.start();
}
@PreDestroy
public void preDestroy() {
redisServer.stop();
}
}
测试案例
@CodeBootTest
class UserServiceImplSpec extends Specification {
@Autowired
private UserService userService;
@Autowired
private RedisTemplate redisTemplate;
def "getById"() {
//sleep(165453646464546)
when: 'start'
UserDO userDO = userService.getById(id)
then: 'assert'
userDO != null
and: 'set value'
def value = userDO.id
expect: 'expect'
value == expectedResult
where: 'sucess'
id || expectedResult
1345368146133819649L || 1345368146133819649L
}
}
7. 测试报告
执行mvn test命令获得以下报告信息;


8. 代码地址
https://github.com/tobebetter9527/freedom-framework/tree/v1.0.0alpha
更多推荐
所有评论(0)