gpt4 book ai didi

go - 如何在 golang 中模拟函数

转载 作者:IT王子 更新时间:2023-10-29 01:50:50 25 4
gpt4 key购买 nike

我写了一个简单的包,基本上由很多getter函数组成。这个包中的每个文件对应一个服务,例如产品文件,包含与产品服务/数据库相关的功能,订单文件到订单服务等。每个功能都将数据库资源作为参数作为底层数据库的参数,以及用于sql,例如。产品编号、名称、订单编号。每个函数都返回一个结构(例如订单、产品)或一个错误:

// product.go

package lib

type Product struct {
ID int
Name string
Price float
}

func GetProductById(DB *sql.DB, ID int) (p Product, err error) {
q := "SELECT * FROM product WHERE id = " + ID
...
}

func GetProductByName(DB *sql.DB, name string) (p Product, err error) {
...
}

// order.go

package lib

type Order struct {
ID int
Date string
Items []items
}

func GetOrderById(DB *sql.DB, ID int) (o Order, err error) {
...
}

问题是我无法从我的主包中模拟这些函数。我真正喜欢做的是重写包,这样我就可以以某种方式将函数传递给一个类型。但我不确定该怎么做。尤其是当函数采用不同的输入参数并返回不同的结构时。有办法做到这一点吗?

最佳答案

在 Go 中,您不能模拟函数或在具体类型上声明的方法。

例如:

func F()

func (T) M()

FM 在 Go 中不可模拟。


但是您可以模拟函数值,无论它们是变量、结构上的字段还是传递给其他函数的参数。

例如:

var Fn = func() { ... }

type S struct {
Fn func()
}

func F(Fn func())

Fn 在所有三种情况下都是可模拟的。


您可以在 Go 中模拟的另一件事是 interface

例如:

type ProductRepository interface {
GetProductById(DB *sql.DB, ID int) (p Product, err error)
}

// the real implementater of the interface
type ProductStore struct{}

func (ProductStore) GetProductById(DB *sql.DB, ID int) (p Product, err error) {
q := "SELECT * FROM product WHERE id = " + ID
// ...
}

// the mock implementer
type ProductRepositoryMock struct {}

func (ProductRepositoryMock) GetProductById(DB *sql.DB, ID int) (p Product, err error) {
// ...
}

现在,任何依赖于 ProductRepository 的代码都可以在“正常模式”下传递一个 ProductStore 类型的值和一个 类型的值>ProductRepositoryMock 测试时。


使用 interface 的另一个选项是定义一个模仿 *sql.DB 然后将该接口(interface)类型用作要传递给您的函数的类型,实现该接口(interface)的模拟版本并在测试期间使用它。

例如:

type DBIface interface {
Query(query string, args ...interface{}) (*sql.Rows, error)
// ...
// It's enough to implement only those methods that
// the functions that depend on DBIface actually use.
// If none of your functions ever calls SetConnMaxLifetime
// you don't need to declare that method on the DBIface type.
}

type DBMock struct {}

func (DBMock) Query(query string, args ...interface{}) (*sql.Rows, error) {
// ...
}

func GetProductByName(DB DBIface, name string) (p Product, err error) {
...
}
GetProductByName

DB 参数现在是可模拟的。

关于go - 如何在 golang 中模拟函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47643192/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com