3 回答

TA貢獻1836條經(jīng)驗 獲得超3個贊
當(dāng)我遇到這種情況時,我的方法是使用我自己的接口作為允許在測試中進行模擬的包裝器。例如。
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()
}
現(xiàn)在,您可以像模擬somepackage.Client接口一樣模擬 Concrete 。
正如@elithrar在下面的評論中指出的那樣,您可以嵌入您想要模擬的類型,因此您只需要添加需要模擬的方法。例如:
type Concrete struct {
*somepackage.Client
}
這樣做后,DoSomethingNotNeedingMocking可以直接調(diào)用其他方法,Concrete而無需將其添加到接口/模擬出來。

TA貢獻1794條經(jīng)驗 獲得超8個贊
根據(jù)情況,您可以應(yīng)用“依賴倒置原則”并利用 Go 的隱式接口。
為此,您在包中定義您的需求接口以及使用情況(而不是定義您在實現(xiàn)它的包中提供的內(nèi)容;就像您在 Java 中一樣)。
然后,您可以獨立于依賴項來測試您的代碼。
具有結(jié)構(gòu)依賴的典型對象:
// Object that relies on a struct
type ObjectUnderTestBefore struct {
db *sql.DB
}
func (o *ObjectUnderTestBefore) Delete() error {
o.db.Exec("DELETE FROM sometable")
}
應(yīng)用依賴倒置原則(帶隱式接口)
// 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 關(guān)注
- 206 瀏覽
添加回答
舉報