我有两个结构: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