Java单元测试学习(一)
使用TestContainer和docker结合启动redis
前提
- docker环境
目录结构
依赖—这里有个小插曲
配置RedisTemplate时一直报错Error creating bean with name ‘redisConnectionFactory’ defined in class path resource [org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.class]: Bean instantiation via factory method failed;---->最后的解决方式是①删除了common-pool2版本号②将jdk的版本从1.8升到了11----->把springboot版本降为2.5.5就不会出现报错
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.6</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.atguigu</groupId><artifactId>redis_springboot</artifactId><version>0.0.1-SNAPSHOT</version><name>redis_springboot</name><description>Demo project for Spring Boot</description><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><!-- test --><testcontainers.version>1.15.3</testcontainers.version><!-- redis --><commons.version>2.9.0</commons.version><!-- lombok --><lombok.version>1.18.12</lombok.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- testcontainer --><dependency><groupId>org.testcontainers</groupId><artifactId>testcontainers</artifactId><version>${testcontainers.version}</version><scope>test</scope></dependency><dependency><groupId>org.testcontainers</groupId><artifactId>junit-jupiter</artifactId><version>${testcontainers.version}</version><scope>test</scope></dependency><!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- spring2.X集成redis所需common-pool2--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
<!-- <version>${commons.version}</version>--></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version><scope>provided</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
相关代码
- RedisConfig
package com.atguigu.redis_springboot.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;import javax.annotation.Resource;@Configuration
public class RedisConfig {@Resourceprivate RedisConnectionFactory connectionFactory;@Beanpublic RedisTemplate<String,Object> redisTemplate() {RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setConnectionFactory(connectionFactory);return redisTemplate;}}
- RedisTestController
package com.atguigu.redis_springboot.controller;import com.atguigu.redis_springboot.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** @author snape* @create 2022-05-28 21:03*/
@RestController
@RequestMapping("/redisTest")
public class RedisTestController {@Resourceprivate RedisService redisService;@GetMappingpublic String testRedis() {//设置值到redisredisService.set("name","tom");//从redis获取值String name = redisService.get("name");return name;}}
- RedisService
package com.atguigu.redis_springboot.service;import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;/*** @author Snape* @create 2023-06-05 11:52* @desc*/
@Component
@RequiredArgsConstructor
public class RedisService {private final RedisTemplate<String, String> redisTemplate;public void set(String key, String value) {redisTemplate.opsForValue().set(key, value);}public String get(String key) {return redisTemplate.opsForValue().get(key);}
}
- RedisSpringbootApplication
package com.atguigu.redis_springboot;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class RedisSpringbootApplication {public static void main(String[] args) {SpringApplication.run(RedisSpringbootApplication.class, args);}}
- application.yml
spring:application:name: redis-springbootredis:database: 0timeout: 1800000lettuce:pool:max-active: 20max-wait: -1max-idle: 5min-idle: 0
- RedisContainer
package com.atguigu.redis_springboot.redis;import org.testcontainers.containers.GenericContainer;/*** @author Snape* @create 2023-06-05 11:41* @desc*/
public class RedisContainer extends GenericContainer<RedisContainer> {public static final String IMAGE_VERSION = "redis:latest";private static final int DEFAULT_PORT = 6379;public RedisContainer() {this(IMAGE_VERSION);}public RedisContainer(String imageVersion) {super(imageVersion == null ? IMAGE_VERSION : imageVersion);addExposedPort(DEFAULT_PORT);start();}public String getPort() {return getMappedPort(DEFAULT_PORT).toString();}}
- RedisServiceTest
package com.atguigu.redis_springboot.service;import com.atguigu.redis_springboot.RedisSpringbootApplicationTests;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;import static org.junit.jupiter.api.Assertions.assertEquals;/*** @author Snape* @create 2023-06-05 13:57* @desc*/
public class RedisServiceTest extends RedisSpringbootApplicationTests {@Autowiredprivate RedisService redisService;@Testpublic void testRedis() {redisService.set("name", "tom");String name = redisService.get("name");assertEquals("tom", name);}@Afterpublic void destroy() {redisContainer.stop();}}
- RedisSpringbootApplicationTests
package com.atguigu.redis_springboot;import com.atguigu.redis_springboot.redis.RedisContainer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit4.SpringRunner;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;@SpringBootTest(classes = RedisSpringbootApplication.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@RunWith(SpringRunner.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@ExtendWith(SpringExtension.class)
@Testcontainers
public abstract class RedisSpringbootApplicationTests {@Containerpublic static final RedisContainer redisContainer =new RedisContainer();@DynamicPropertySourcepublic static void registerProperties(DynamicPropertyRegistry registry) {registry.add("spring.redis.host", redisContainer::getHost);registry.add("spring.redis.port", redisContainer::getPort);}}
测试
-
在test方法里打上断点,开启debug后可查看到启动的容器
-
测试通过