数据库

数据库测试

数据库测试指的是测试你的应用如何与数据库交互。这包括测试写入数据库的内容、如何在测试前运行迁移,以及如何在测试之间保持数据库整洁。

迁移数据库

在执行与数据库交互的测试之前,你会希望先运行迁移。为此,testUtils 服务中提供了两个钩子,你可以在 tests/bootstrap.ts 文件中配置它们。

每个运行周期后重置数据库

我们的第一个选项是 testUtils.db().migrate()。这个钩子会先运行你所有的迁移,然后再全部回滚。

tests/bootstrap.ts
import testUtils from '@adonisjs/core/services/test_utils'
export const runnerHooks: Required<Pick<Config, 'setup' | 'teardown'>> = {
setup: [
() => testUtils.db().migrate(),
],
teardown: [],
}

在这里配置这个钩子后,将会发生以下情况:

  • 在运行测试之前,会执行迁移。
  • 在测试结束时,数据库将被回滚。

因此,每次运行测试时,我们都将拥有一个全新且空的数据库。

每个运行周期后清空表

在每个运行周期后重置数据库是一个不错的选项,但如果你有大量迁移,它可能会很慢。另一个选项是在每个运行周期后清空表。这个选项会更快,因为迁移只会执行一次:也就是你在全新数据库上第一次运行测试的时候。

在每个运行周期结束时,表只会被清空,但我们的 schema 会被保留。因此,下次运行测试时,我们将拥有一个空的数据库,但 schema 已经就位,无需再次运行所有迁移。

tests/bootstrap.ts
import testUtils from '@adonisjs/core/services/test_utils'
export const runnerHooks: Required<Pick<Config, 'setup' | 'teardown'>> = {
setup: [
() => testUtils.db().truncate(),
],
}

填充数据库种子

如果你需要为数据库填充种子数据,可以使用 testUtils.db().seed() 钩子。这个钩子会在运行测试之前运行你所有的种子文件。

tests/bootstrap.ts
import testUtils from '@adonisjs/core/services/test_utils'
export const runnerHooks: Required<Pick<Config, 'setup' | 'teardown'>> = {
setup: [
() => testUtils.db().seed(),
],
}

在测试之间保持数据库整洁

全局事务

运行测试时,你可能希望在每个测试之间保持数据库整洁。为此,你可以使用 testUtils.db().withGlobalTransaction() 钩子。这个钩子会在每个测试之前开启一个事务,并在测试结束时将其回滚。

tests/unit/user.spec.ts
import { test } from '@japa/runner'
import testUtils from '@adonisjs/core/services/test_utils'
test.group('User', (group) => {
group.each.setup(() => testUtils.db().withGlobalTransaction())
})

请注意,如果你在被测代码中使用了任何事务,这将不起作用,因为事务无法嵌套。在这种情况下,你可以改用 testUtils.db().migrate()testUtils.db().truncate() 钩子。

清空表

如上所述,如果你在被测代码中使用了事务,全局事务将不起作用。在这种情况下,你可以使用 testUtils.db().truncate() 钩子。这个钩子会在每个测试之后清空你所有的表。

tests/unit/user.spec.ts
import { test } from '@japa/runner'
test.group('User', (group) => {
group.each.setup(() => testUtils.db().truncate())
})