You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何Mock测试GetTables函数?无需真实数据库连接及测试代码编写

问题描述

我有一个依赖pgxpool.Pool的Go语言GetTables函数,代码如下:

func GetTables(pool *pgxpool.Pool, session *session.Store, enforcer *casbin.Enforcer) fiber.Handler {
    return func(ctx *fiber.Ctx) error {
        rows, err := pool.Query(context.Background(), "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'")
        if err != nil {
            return err
        }
        defer rows.Close()

        var tables []string

        for rows.Next() {
            var tableName string
            if err := rows.Scan(&tableName); err != nil {
                return err
            }
            tables = append(tables, tableName)
        }

        err = ctx.JSON(tables)
        if err != nil {
            panic("Error occurred when returning users JSON: " + err.Error())
        }
        return err
    }
}

现在需要实现Mock机制来测试这个函数,不需要创建真实的数据库连接,请求协助编写对应的测试函数。

解决方案

我们可以使用pgxmock库模拟pgxpool.Pool的行为,实现无真实数据库的测试,以下是完整的测试实现:

测试逻辑说明

  1. 创建pgxmock.PgxPoolIface的mock实例,替代真实的数据库连接池
  2. 预设mock对目标SQL查询的响应,模拟返回的表名数据
  3. 构建Fiber测试上下文,调用GetTables返回的handler
  4. 验证handler的响应是否符合预期,同时确认mock的预期调用是否全部完成

完整测试代码

package yourpackage

import (
	"context"
	"testing"

	"github.com/gofiber/fiber/v2"
	"github.com/pashagolub/pgxmock"
	"github.com/stretchr/testify/assert"
)

func TestGetTables(t *testing.T) {
	// 创建pgx mock连接池
	mockPool, err := pgxmock.NewPool()
	assert.NoError(t, err)
	defer mockPool.Close()

	// 定义预期返回的表名数据
	expectedTables := []string{"users", "products", "orders"}

	// 设置mock预期:匹配指定SQL查询,返回模拟结果集
	mockPool.ExpectQuery("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'").
		WillReturnRows(pgxmock.NewRows([]string{"table_name"}).
			AddRow(expectedTables[0]).
			AddRow(expectedTables[1]).
			AddRow(expectedTables[2]))

	// 初始化Fiber测试应用
	app := fiber.New()
	// 注册测试路由,传入mock池及空的session、enforcer参数
	app.Get("/tables", GetTables(mockPool, nil, nil))

	// 构造测试请求
	req := app.Test(t, fiber.AcquireRequest())
	req.Method = fiber.MethodGet
	req.RequestURI = "/tables"
	defer fiber.ReleaseRequest(req)

	// 发送请求并获取响应
	resp, err := app.Test(req)
	assert.NoError(t, err)
	defer resp.Body.Close()

	// 验证响应状态码
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	// 解析响应体,验证返回数据是否符合预期
	var returnedTables []string
	err = fiber.Unmarshal(resp.Body, &returnedTables)
	assert.NoError(t, err)
	assert.Equal(t, expectedTables, returnedTables)

	// 验证mock的所有预期调用均已执行
	assert.NoError(t, mockPool.ExpectationsWereMet())
}

注意事项

  • 需提前通过go get安装pgxmock和testify依赖
  • 测试中忽略了session和casbin.Enforcer参数(传入nil),如果业务逻辑需要这两个参数的行为,可以对它们做同样的Mock处理
  • 原函数中ctx.JSON失败会触发panic,若需覆盖该场景,可以在测试中添加panic捕获逻辑

内容的提问来源于stack exchange,提问作者sachin prajapati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:32:41