如何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的行为,实现无真实数据库的测试,以下是完整的测试实现:
测试逻辑说明
- 创建
pgxmock.PgxPoolIface的mock实例,替代真实的数据库连接池 - 预设mock对目标SQL查询的响应,模拟返回的表名数据
- 构建Fiber测试上下文,调用
GetTables返回的handler - 验证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
相关产品推荐
相关产品推荐

