pg_mockable

为测试创建可 Mock 的 PostgreSQL 函数包装器

概览

扩展包名版本分类许可证语言
pg_mockable1.1.0LANGPostgreSQLSQL
ID扩展名BinLibLoadCreateTrustReloc模式
3120pg_mockablemockable

版本

类型仓库版本PG 大版本包名依赖
EXTPIGSTY1.1.01817161514pg_mockable-
RPMPIGSTY1.1.01817161514pg_mockable_$v-
DEBPIGSTY1.1.01817161514postgresql-$v-pg-mockable-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
d12.aarch64
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
d13.x86_64
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
d13.aarch64
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
u22.x86_64
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
u22.aarch64
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
u24.x86_64
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
u24.aarch64
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
u26.x86_64
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
u26.aarch64
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0
PIGSTY 1.1.0

构建

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

pig build pkg pg_mockable         # 构建 DEB 包

安装

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

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

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

pig install pg_mockable;          # 当前活跃 PG 版本安装
pig ext install -y pg_mockable -v 18  # PG 18
pig ext install -y pg_mockable -v 17  # PG 17
pig ext install -y pg_mockable -v 16  # PG 16
pig ext install -y pg_mockable -v 15  # PG 15
pig ext install -y pg_mockable -v 14  # PG 14
dnf install -y pg_mockable_18       # PG 18
dnf install -y pg_mockable_17       # PG 17
dnf install -y pg_mockable_16       # PG 16
dnf install -y pg_mockable_15       # PG 15
dnf install -y pg_mockable_14       # PG 14
apt install -y postgresql-18-pg-mockable   # PG 18
apt install -y postgresql-17-pg-mockable   # PG 17
apt install -y postgresql-16-pg-mockable   # PG 16
apt install -y postgresql-15-pg-mockable   # PG 15
apt install -y postgresql-14-pg-mockable   # PG 14

创建扩展

CREATE EXTENSION pg_mockable;

用法

来源:pg_mockable upstream READMEPGXN pg_mockablelocal metadata、本地源码归档 pg_mockable-1.1.0.tar.gz

pg_mockable 用于为 PostgreSQL 函数创建可 Mock 的包装函数。它主要面向数据库测试:应用代码调用稳定的包装函数,而测试可以临时替换包装函数的返回值。

CREATE EXTENSION pg_mockable CASCADE;

该扩展会安装到固定的 mockable schema 中,且不可重定位。

Mock 内置时间函数

mockable.now() 已经预先创建,因为 Mock now() 也会覆盖该扩展暴露的一组当前时间包装函数。

SELECT mockable.now();

SELECT mockable.mock(
  'pg_catalog.now()',
  '2026-06-17 10:00:00+08'::timestamptz
);

SELECT mockable.now();
SELECT mockable.current_timestamp();
SELECT mockable.current_date();

CALL mockable.unmock('pg_catalog.now()');

mockable.mock(regprocedure, anyelement) 会保存 mock 值并返回它。mockable.unmock(regprocedure) 会清除 mock,并让包装函数恢复为调用原始函数。

包装应用函数

使用 mockable.wrap_function()mockable schema 中创建一个薄包装函数:

CREATE SCHEMA app;

CREATE FUNCTION app.answer()
RETURNS int
LANGUAGE sql
RETURN 42;

SELECT mockable.wrap_function('app.answer()');

SELECT mockable.answer();                 -- 42
SELECT mockable.mock('app.answer()', 7);   -- 7
SELECT mockable.answer();                 -- 7

CALL mockable.unmock('app.answer()');
SELECT mockable.answer();                 -- 42

第一个参数是 regprocedure,因此函数存在重载时需要写出参数类型:

SELECT mockable.wrap_function('pg_catalog.current_setting(text, boolean)');

如果自动生成包装函数不够用,可以把精确的 CREATE OR REPLACE FUNCTION 语句作为第二个参数传入:

SELECT mockable.wrap_function(
  'app.answer()',
  $$
  CREATE OR REPLACE FUNCTION mockable.answer()
  RETURNS int
  LANGUAGE sql
  RETURN app.answer();
  $$
);

Mock 生命周期

默认 mock 生命周期是事务级的。若值需要跨 dump/restore 或后续事务保留,可以在创建包装函数时使用持久生命周期:

SELECT mockable.wrap_function(
  'app.answer()',
  mock_duration$ => 'PERSISTENT'
);

测试夹具不再需要持久 mock 时,应显式清除:

CALL mockable.unmock('app.answer()');

Search Path 注意事项

应用代码必须实际调用包装函数,例如 mockable.now()mockable.answer(),mock 才会生效。某些 PL/pgSQL 代码可以通过调整 search_path 重定向,但表默认值等表达式会被编译为函数 OID;事后再把 mockable 加进 search_path 不会改写这些引用。需要可测试的代码应优先显式调用 mockable.*

注意事项

  • Pigsty 将 pg_mockable 1.1.0 打包给 PostgreSQL 14-18。它是 SQL 扩展,不需要 shared_preload_libraries
  • pg_mockable 拥有 mockable schema;control 文件不支持把它安装到其他 schema。
  • 包装函数权限来自被包装的原函数。上游测试会验证:包装一个私有函数不会把执行权限授予原本无法调用该函数的角色。

最后修改 2026-06-18: extension data update (63e2bd9)