在 Go 中,模拟在具体类型上声明的函数,例如 func F() {}而 func (T) M() {} 是不可能的。然而,还有其他方法可以实现类似的功能。
Go 允许模拟函数值,无论它们是存储在变量中、作为结构体上的字段还是作为传递给其他函数的参数。例如,考虑以下情况:
var Fn = func() { ... } type S struct { Fn func() } func F(Fn func())
在所有三种情况下,Fn 都是可模拟的。
Go 中更优选的模拟方法是使用接口。例如:
type ProductRepository interface { GetProductById(DB *sql.DB, ID int) (p Product, err error) } // The real implementer type ProductStore struct{} func (ProductStore) GetProductById(DB *sql.DB, ID int) (p Product, err error) { q := "SELECT * FROM product WHERE id = ?" // ... } // The mock implementer type ProductRepositoryMock struct{} func (ProductRepositoryMock) GetProductById(DB *sql.DB, ID int) (p Product, err error) { // ... }
任何依赖于 ProductRepository 的代码现在都可以在正常场景中使用 ProductStore,并在测试期间使用 ProductRepositoryMock。
另一个允许保留现有函数声明的模拟选项是定义一个模仿 *sql.DB 方法的接口并使用它 反而。例如:
type DBIface interface { Query(query string, args ...interface{}) (*sql.Rows, error) // Only declare methods that are actually used. } 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 中的函数?的详细内容。更多信息请关注PHP中文网其他相关文章!