3 回答

TA贡献1836条经验 获得超3个赞
当我遇到这种情况时,我的方法是使用我自己的接口作为允许在测试中进行模拟的包装器。例如。
type MyInterface interface {
DoSomething(i int) error
DoSomethingElse() ([]int, error)
}
type Concrete struct {
client *somepackage.Client
}
func (c *Concrete) DoSomething(i int) error {
return c.client.DoSomething(i)
}
func (c *Concrete) DoSomethingElse() ([]int, error) {
return c.client.DoSomethingElse()
}
现在,您可以像模拟somepackage.Client接口一样模拟 Concrete 。
正如@elithrar在下面的评论中指出的那样,您可以嵌入您想要模拟的类型,因此您只需要添加需要模拟的方法。例如:
type Concrete struct {
*somepackage.Client
}
这样做后,DoSomethingNotNeedingMocking可以直接调用其他方法,Concrete而无需将其添加到接口/模拟出来。

TA贡献1794条经验 获得超8个赞
根据情况,您可以应用“依赖倒置原则”并利用 Go 的隐式接口。
为此,您在包中定义您的需求接口以及使用情况(而不是定义您在实现它的包中提供的内容;就像您在 Java 中一样)。
然后,您可以独立于依赖项来测试您的代码。
具有结构依赖的典型对象:
// Object that relies on a struct
type ObjectUnderTestBefore struct {
db *sql.DB
}
func (o *ObjectUnderTestBefore) Delete() error {
o.db.Exec("DELETE FROM sometable")
}
应用依赖倒置原则(带隐式接口)
// subset of sql.DB which defines our "requirements"
type dbExec interface {
Exec(query string, args ...interface{}) (sql.Result, error)
}
// Same object with it's requirement defined as an local interface
type ObjectUnderTestWithDIP struct {
// *sql.DB will implicitly implement this interface
db dbExec
}
func (o *ObjectUnderTestWithDIP) Delete() error {
o.db.Exec("DELETE FROM sometable")
}
- 3 回答
- 0 关注
- 217 浏览
添加回答
举报