如何使用Mockery正确模拟clickhouse-go.driver.Row.Scan方法以填充参数值?
如何使用Mockery正确模拟clickhouse-go.driver.Row.Scan方法以填充参数值?
我明白你现在遇到的问题了——想通过Mockery模拟Scan方法,把值填充到传入的指针参数里,但直接给args[0]赋值根本没生效,对吧?这其实是Go里值传递的特性导致的,我来给你讲清楚怎么解决。
问题根源
你当前的代码里,args[0] = 1只是把切片中存储的指针副本替换成了整数1,并没有修改原来指针指向的内存区域。因为Go的函数参数是值传递,切片args里的每个元素都是传入参数的副本,所以直接修改args[0]不会影响到测试代码里的avg变量。
正确解决方案
正确的做法是先把args[0]转换成对应的指针类型,然后通过解引用修改它指向的内存值。下面是修改后的完整测试代码:
import "fmt" func Test_1(test *testing.T) { test.Parallel() ch := ch_mock.NewMockConn(test) row := ch_mock.NewMockRow(test) row.EXPECT().Scan(mock.AnythingOfType("*int64")).RunAndReturn(func(args ...any) error { // 类型断言,确保第一个参数是*int64类型 dest, ok := args[0].(*int64) if !ok { return fmt.Errorf("unexpected type for first argument: %T", args[0]) } // 修改指针指向的实际内存值 *dest = 1 return nil }) ch.EXPECT().QueryRow(mock.Anything, mock.Anything).Return(row) // 这里将ch注入到待测试的代码中... }
这样当你的业务代码调用row.Scan(&avg)时,Mock里的代码会拿到&avg的指针副本,通过解引用*dest修改它指向的内存,avg自然就会被设置成1了。
扩展:处理多参数场景
如果需要同时填充多个不同类型的参数,比如int64和string,可以这样扩展代码:
row.EXPECT().Scan(mock.AnythingOfType("*int64"), mock.AnythingOfType("*string")).RunAndReturn(func(args ...any) error { // 处理第一个int64参数 if destInt, ok := args[0].(*int64); ok { *destInt = 1 } else { return fmt.Errorf("expected *int64 for first arg, got %T", args[0]) } // 处理第二个string参数 if destStr, ok := args[1].(*string); ok { *destStr = "test_result" } else { return fmt.Errorf("expected *string for second arg, got %T", args[1]) } return nil })
备注:内容来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

