pgsqlmock

为 PostgreSQL 单元测试提供函数 Mock、表和视图伪造能力

概览

扩展包名版本分类许可证语言
pgsqlmock1.0.1LANGPostgreSQLSQL
ID扩展名BinLibLoadCreateTrustReloc模式
3130pgsqlmock-
相关扩展plpgsql pgtap pgtap pg_mockable faker unit

Packaging corrects the upstream control dependency name from pgTap to pgtap and requires pgTAP 1.3.4 or newer.

版本

类型仓库版本PG 大版本包名依赖
EXTPIGSTY1.0.11817161514pgsqlmockplpgsql, pgtap
RPMPIGSTY1.0.11817161514pgsqlmock_$vpgtap_$v
DEBPIGSTY1.0.11817161514postgresql-$v-pgsqlmockpostgresql-$v-pgtap
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
d12.aarch64
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
d13.x86_64
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
d13.aarch64
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
u22.x86_64
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
u22.aarch64
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
u24.x86_64
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
u24.aarch64
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
u26.x86_64
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
u26.aarch64
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1
PIGSTY 1.0.1

构建

您可以使用 pig build 命令构建 pgsqlmock 扩展的 RPM / DEB 包:

pig build pkg pgsqlmock         # 构建 RPM / DEB 包

安装

您可以直接安装 pgsqlmock 扩展包的预置二进制包,首先确保 PGDGPIGSTY 仓库已经添加并启用:

pig repo add pgsql -u          # 添加仓库并更新缓存

使用 pig 或者是 apt/yum/dnf 安装扩展:

pig install pgsqlmock;          # 当前活跃 PG 版本安装
pig ext install -y pgsqlmock -v 18  # PG 18
pig ext install -y pgsqlmock -v 17  # PG 17
pig ext install -y pgsqlmock -v 16  # PG 16
pig ext install -y pgsqlmock -v 15  # PG 15
pig ext install -y pgsqlmock -v 14  # PG 14
dnf install -y pgsqlmock_18       # PG 18
dnf install -y pgsqlmock_17       # PG 17
dnf install -y pgsqlmock_16       # PG 16
dnf install -y pgsqlmock_15       # PG 15
dnf install -y pgsqlmock_14       # PG 14
apt install -y postgresql-18-pgsqlmock   # PG 18
apt install -y postgresql-17-pgsqlmock   # PG 17
apt install -y postgresql-16-pgsqlmock   # PG 16
apt install -y postgresql-15-pgsqlmock   # PG 15
apt install -y postgresql-14-pgsqlmock   # PG 14

创建扩展

CREATE EXTENSION pgsqlmock CASCADE;  -- 依赖: plpgsql, pgtap

用法

来源:

pgsqlmock 扩展了 pgTAP,增加了表模拟、函数和视图模拟、调用次数断言以及调试辅助功能。其辅助功能会修改或替换真实的数据库对象,因此需要在基于事务的测试上下文中使用它们,以便在测试结束后回滚这些更改。

CREATE EXTENSION pgtap;
CREATE EXTENSION pgsqlmock;

模拟表

fake_table(text[], ...) 可以隔离测试与外键、主键、NOT NULL 约束、分区或预存行之间的关系。将模式限定的表名作为 text[] 传递:

SELECT plan(2);

SELECT fake_table(
  _table_ident       => ARRAY['app.accounts', 'app.transactions'],
  _make_table_empty  => true,
  _leave_primary_key => false,
  _drop_not_null     => true
);

INSERT INTO app.transactions(account_id, amount)
VALUES (999, 42.00);

SELECT is(
  (SELECT sum(amount) FROM app.transactions WHERE account_id = 999),
  42.00::numeric,
  'transaction logic is isolated from account fixtures'
);

SELECT * FROM finish();

重要选项包括 make_table_emptyleave_primary_keydrop_not_nulldrop_collationdrop_partitions。在测试中保留主键同时删除参与列的 NOT NULL 约束是矛盾的;对于这种测试形状,需要显式地移除或重新创建该键。

模拟函数

mock_func(schema, name, signature, ...) 临时替换一个例行程序,但保持其身份不变。提供标量值或 SQL/准备语句文本作为结果集:

CREATE OR REPLACE FUNCTION app.current_business_time()
RETURNS time LANGUAGE sql AS $$ SELECT current_time $$;

SELECT mock_func(
  'app',
  'current_business_time',
  '()',
  _return_scalar_value => '13:00'::time
);

SELECT is(app.current_business_time(), '13:00'::time, 'clock is deterministic');

对于返回集合的例行程序,请传递 _return_set_value 作为 SQL 查询或已准备语句的名称。使用 get_routine_signature() 来确定在重载或默认参数使存储签名模糊时的存储签名。

模拟视图

mock_view(schema, view_name, return_set_sql) 替换一个带有受控行数的视图:

SELECT mock_view(
  'app',
  'active_accounts',
  $$SELECT * FROM (VALUES (1, 'test')) AS v(id, name)$$
);

SELECT results_eq(
  'SELECT id, name FROM app.active_accounts',
  $$VALUES (1, 'test')$$,
  'view consumer sees only the fixture'
);

调用次数和诊断信息

在使用 track_functions = 'all' 断言例行程序被调用的次数之前,请设置 call_count()

SET LOCAL track_functions = 'all';

SELECT call_count(
  1,
  'app',
  'current_business_time',
  '()'
);

print_table_as_json()print_query_as_json() 通过 NOTICE 发出可重复的 SQL/JSON 样式快照,这对于当 pgTAP 的回滚会隐藏失败测试期间创建的状态时非常有用。

注意事项

  • 只在隔离的测试事务中运行模拟和表模拟;它们会发出真实的 ALTERDROP 和替换 DDL。
  • pgSQLMock 依赖于 PL/pgSQL 和 pgTAP。在运行其断言之前,请加载 pgTAP。
  • call_count() 依赖于 PostgreSQL 函数统计信息,因此需要设置 track_functions = 'all'
  • 发行版 1.0.1 修复了 fake_table() 在没有主键的表上删除 NOT NULL 约束的问题。