我有兩個結構:FunctionalityClient
和TestClient
,都執行Interface
。我有一個類型Interface
的全局變量Client
。我將Client
分配給實際客戶端或模擬客戶端,具體取決於它是測試還是正常運行。如何在Golang中使用成員函數正確地模擬結構?
Interface
有一個方法Request
,我想模擬測試。也就是說,我想:
- 記錄什麼是傳遞給函數的
- 返回參數從功能
一些任意定義的返回值,因此結構是這樣的:
type TestClient struct {
recordedArgs []interface{}
returnValues []interface{}
}
func (c *TestClient) Request(body io.Reader, method string, endpoint string, headers []Header) ([]byte, error) {
c.recordedArgs = append(c.recordedArgs, []interface{}{body, method, endpoint, headers}) // this can't be typed if I want the code to be reusable
if len(c.returnValues) != 0 {
last := c.returnValues[0]
c.returnValues = c.returnValues[1:]
return last.([]byte), nil
}
return nil, nil
}
我用它像這樣:
testClient := TestClient{
returnValues: []interface{}{
[]byte("arbitrarily defined return value"),
[]byte("this will be returned after calling Request a second time"),
}
}
Client = &testClient
// run the test
// now let's check the results
r1 := testClient.recordedArgs[1].([]interface{}) // because I append untyped lists to recordedArgs
assert.Equal(t, "POST", r1[1].(string))
assert.Equal(t, "/file", r1[2].(string))
// and so on
現在的問題。
我有幾個結構,我想嘲笑這樣的。目前我只是複製並粘貼上面的代碼爲每個結構。但這真的很糟糕,我希望模擬邏輯能夠以某種方式被抽象出來。我也會接受像Mockito的when
這樣的東西:當使用特定參數調用模擬函數時,返回一個特定值並記錄調用。
我怎樣才能正確地模擬一個結構與Golang中的成員函數?
因爲您知道每個元素都將是[] interface {},所以您可以通過設置recordedArgs a [] [] interface {}來簡化這一點。它爲您節省了一些不必要的類型斷言。 – Adrian