xhd2015 / xgo

All-in-one go testing library
MIT License
289 stars 16 forks source link

mock patch带泛型结构体的方法panic #211

Closed hong-ke closed 1 week ago

hong-ke commented 1 week ago

报错 === RUN TestGeneric --- FAIL: TestGeneric (2.43s) panic: failed to setup mock for: subject/service.GenericSt[...].GetData-fm [recovered] panic: failed to setup mock for: subject/service.GenericSt[...].GetData-fm

示例代码: type GenericSt[T any] struct { Data T }

func (g GenericSt[T]) GetData(param T) T { return param }

type Inner struct { }

func TestGeneric(t *testing.T) {

mock.Patch(GenericSt[Inner]{}.GetData, func(Inner) Inner {
    return Inner{}
})
fmt.Println("done")

}

如果将inner改为基础类型,如int则可正常运行 func TestGeneric(t *testing.T) {

mock.Patch(GenericSt[int]{}.GetData, func(int) int {
    return 1
})
fmt.Println("done")

}

xhd2015 commented 1 week ago

问题已收到

xhd2015 commented 1 week ago

@hong-ke 这个问题的原因找到了,ParseFuncName在遇到含有/的类型时会解析错误,所以基本类型可以解析出来,而非基本类型解析错误:

image

PR https://github.com/xhd2015/xgo/pull/220 解决了这个问题。

升级xgo v1.0.41指引:

# update xgo
go install github.com/xhd2015/xgo/cmd/xgo@v1.0.41

# update dependency
go get github.com/xhd2015/xgo/runtime@v1.0.41

感谢反馈!

hong-ke commented 1 week ago

尝试了一下,这个case好了,但我有个疑问,泛型struct中的成员参数值不同,mock会失败,是设计如此吗,下面case中Num值不同会mock失败

type GenericSt[T any] struct { Data T }

func (g GenericSt[T]) GetData(param T) T { return param }

type Inner struct { Num int }

func TestGeneric(t *testing.T) { v := GenericSt[Inner]{Data: Inner{}} var mocked bool mock.Patch(v.GetData, func(Inner) Inner { mocked = true return Inner{} }) test2() fmt.Println(mocked) fmt.Println("done") }

func test2() { GenericSt[Inner]{Data: Inner{Num: 11}}.GetData(Inner{}) }

xhd2015 commented 1 week ago

这个是有意设计如此的,不同实例的mock是隔离的。 如果想要对所有实例进行mock,通过下面的方式:

mock.Patch(GenericSt[Inner].GetData,  func(GenericSt[Inner], Inner) Inner {
    return Inner{}
})

注意函数里面多了一个参数: GenericSt[Inner]

hong-ke commented 1 week ago

了解了,感谢解答