Wordz – 我们数据库的集成测试
在这一部分,我们将回顾 Wordz 应用程序的集成测试,以便对其有一个直观的了解。我们将在第 14 章《驱动数据库层》和第 15 章《驱动Web层》中详细介绍如何编写这些测试以及如何设置测试工具。
从数据库中获取单词
在我们之前的设计工作中,我们确定了 Wordz 需要一个地方来存储待猜测的候选单词。我们定义了一个名为 WordRepository
的接口,以将我们与存储细节隔离。在那个迭代中,我们只定义了一个接口方法:
public interface WordRepository {
String fetchWordByNumber(int wordNumber);
}
WordRepository
接口的实现将访问数据库并返回给定 wordNumber
的单词。我们将在第 14 章《驱动数据库层》中实现这一点。现在,让我们先大致看一下集成测试的样子。该测试使用开源库来帮助编写测试并提供数据库。我们选择了以下工具:
-
database-rider:一个开源库(可从 https://databaserider.github.io/getting-started/ 获取),作为测试工具。
-
Postgres:一个流行的开源关系数据库,用于存储我们的数据。
以下是测试代码:
package com.wordz.adapters.db;
import com.github.database.rider.core.api.connection.ConnectionHolder;
import com.github.database.rider.core.api.dataset.DataSet;
import com.github.database.rider.junit5.api.DBRider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.postgresql.ds.PGSimpleDataSource;
import javax.sql.DataSource;
import static org.assertj.core.api.Assertions.assertThat;
@DBRider
public class WordRepositoryPostgresTest {
private DataSource dataSource;
@BeforeEach
void beforeEachTest() {
var ds = new PGSimpleDataSource();
ds.setServerNames(new String[]{"localhost"});
ds.setDatabaseName("wordzdb");
ds.setUser("ciuser");
ds.setPassword("cipassword");
this.dataSource = ds;
}
private final ConnectionHolder connectionHolder = () -> dataSource.getConnection();
@Test
@DataSet("adapters/data/wordTable.json")
public void fetchesWord() {
var adapter = new WordRepositoryPostgres(dataSource);
String actual = adapter.fetchWordByNumber(27);
assertThat(actual).isEqualTo("ARISE");
}
}
fetchesWord()
测试方法由 @DataSet
注解标记。该注解由 database-rider
测试框架提供,它构成了我们测试的 Arrange 步骤。它指定了一个已知的测试数据文件,框架将在测试运行前将其加载到数据库中。数据文件位于 src/test/resources
根文件夹下。注解中的参数给出了其余路径。在我们的例子中,文件将位于 src/test/resources/adapters/data/wordTable.json
。其内容如下:
{
"WORD": [
{
"id": 1,
"number": 27,
"text": "ARISE"
}
]
}
这个 JSON 文件告诉 database-rider
框架,我们希望将一行数据插入名为 WORD
的数据库表中,列值为 1
、27
和 ARISE
。
我们暂时不会编写适配器代码来使这个测试通过。我们需要采取几个步骤才能使这个测试编译通过,包括下载各种库并启动 Postgres 数据库。我们将在第 14 章《驱动数据库层》中详细介绍这些步骤。
这段集成测试代码的概述是,它正在测试一个我们将要编写的新类 WordRepositoryPostgres
。该类将包含数据库访问代码。我们可以看到明显的 JDBC 对象 javax.sql.DataSource
,它代表一个数据库实例。这是我们正在测试与数据库集成的线索。我们可以看到来自数据库测试库的新注解:@DBRider
和 @DataSet
。最后,我们可以看到一些熟悉的内容——测试的 Arrange、Act 和 Assert 步骤:
-
Arrange 步骤创建了一个
WordRepositoryPostgres
对象,该对象将包含我们的数据库代码。它与database-rider
库的@DataSet
注解一起工作,在测试运行前将一些已知数据放入数据库。 -
Act 步骤调用
fetchWordByNumber()
方法,传入我们要测试的数字wordNumber
。这个数字与wordTable.json
文件的内容对齐。 -
Assert 步骤确认从数据库返回的预期单词是
ARISE
。
正如我们所看到的,集成测试本质上与单元测试并没有太大区别。