我有一个方法在我用于数据库访问的类型上使用target interface{}
,如:
func (c *client) Query(query someType, target interface{}) error {
return c.db.Query(query).Decode(target)
}
然后将其称为
result := resultType{}
if err := c.Query(myQuery, &result); err == nil {
// do sth with result
}
当我传递result
我现在遇到的麻烦是我不知道如何在测试中模仿这种行为(改变传递的引用)。
如果我不需要通过interface{}
,我可以想象它是这样做的:
type mockClient struct {
targetValue resultType
}
func (m *mockClient) Query(query someType, target *resultType) error {
*target = m.targetValue
return nil
}
如果我尝试使用我的实际签名做同样的事情,我无法取消引用target
中包含的值,如下所示:
type mockClient struct {
targetValue interface{}
}
func (m *mockClient) Query(query someType, target interface{}) error {
target = m.targetValue // this does not mutate the passed target
return nil
}
当它作为空接口传入时,是否可以取消引用指针值?如果不可能,那么测试副方法的另一种方法是什么,而不必使用具体类型作为参数?
答案 0 :(得分:1)
您可以使用'reflect'包来执行此操作。
package main
import (
"fmt"
"reflect"
)
type mockClient struct {}
func (m *mockClient) Query(query string, target interface{}) error {
a := "changed"
va := reflect.ValueOf(a)
reflect.ValueOf(target).Elem().Set(va)
return nil
}
func main() {
var mc mockClient
target := "initial"
mc.Query("qwe", &target)
fmt.Println(target)
}
引用您的简单示例可以找到here