以下是一個簡單的基於testcontainers 的測試(基於java 項目)
預備環境
因為testcontainers 基於docker 運行,所以需要安裝docker 引擎
項目准備
- 項目結構
├── README.md
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── dalong
│ │ ├── Cache.java
│ │ └── RedisBackedCache.java
│ └── resources
└── test
└── java
└── RedisTest.java
pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dalong</groupId>
<artifactId>redit-test</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<encoding>UTF-8</encoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.12.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.rnorth.visible-assertions</groupId>
<artifactId>visible-assertions</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies>
</project>
- 代碼說明
main 為主要實現,一個cache接口定義cache 契約,RedisBackedCache 為基於redis 的實現,RedisTest 為基於testcontainers 的測試用例
以下主要說明RedisTest.java 代碼(基於junit 的測試)
import com.dalong.Cache;
import com.dalong.RedisBackedCache;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.testcontainers.containers.GenericContainer;
import redis.clients.jedis.Jedis;
import java.util.Optional;
import static org.rnorth.visibleassertions.VisibleAssertions.*;
public class RedisTest {
// 核心使用GenericContainer 模擬redis 服務,同時使用了固定端口,使用jedis 訪問
@Rule
public GenericContainer redis = new GenericContainer("redis:3.0.6")
.withExposedPorts(6379);
private Cache cache;
@Before
public void setUp() throws Exception {
Jedis jedis = new Jedis(redis.getContainerIpAddress(), redis.getMappedPort(6379));
cache = new RedisBackedCache(jedis, "test");
}
@Test
public void testFindingAnInsertedValue() {
cache.put("foo", "FOO");
Optional<String> foundObject = cache.get("foo", String.class);
assertTrue("When an object in the cache is retrieved, it can be found",
foundObject.isPresent());
assertEquals("When we put a String in to the cache and retrieve it, the value is the same",
"FOO",
foundObject.get());
}
@Test
public void testNotFindingAValueThatWasNotInserted() {
Optional<String> foundObject = cache.get("bar", String.class);
assertFalse("When an object that's not in the cache is retrieved, nothing is found",
foundObject.isPresent());
}
}
說明
使用testcontainers 我們可以進行實際數據庫的測試(數據庫特性、版本)有一篇關於不要使用內存數據庫mock 的
文章可以看看和嗯不錯 https://phauer.com/2017/dont-use-in-memory-databases-tests-h2/
參考資料
https://github.com/rongfengliang/testcontainer-learning
https://github.com/testcontainers/testcontainers-java
https://testcontainers.org/
https://phauer.com/2017/dont-use-in-memory-databases-tests-h2/
