最近基于工作需要,在使用了 gomonkey 遇到很多问题之后,并且也担心基于 Assembly 的方式对未来单测维护的不可持续性,开发了 xgo 。
xgo 基于 IR 中间码重写,更加贴近源代码而不是机器码。所以兼容性比 Assembly 要好很多,功能也更强。
下面是一个简单的示例:
package demo
import (
"context"
"testing"
"github.com/xhd2015/xgo/runtime/core"
"github.com/xhd2015/xgo/runtime/mock"
)
func MyFunc() string {
return "my func"
}
func TestFuncMock(t *testing.T) {
mock.Mock(MyFunc, func(ctx context.Context, fn *core.FuncInfo, args core.Object, results core.Object) error {
results.GetFieldIndex(0).Set("mock func")
return nil
})
text := MyFunc()
if text != "mock func" {
t.Fatalf("expect MyFunc() to be 'mock func', actual: %s", text)
}
}
欢迎大家使用和提意见
![]() |
1
mightybruce 2024-03-28 10:51:56 +08:00 ![]() 行,关注了。
|
2
xhd2015 OP 说明一下:该 mock 不需要基于接口进行 monkey ,开箱可用😃
|
3
oceana 2024-03-28 12:59:10 +08:00 ![]() 点个赞
|
![]() |
5
sophos 2024-03-28 19:22:58 +08:00
|
![]() |
7
sophos 2024-03-28 19:48:22 +08:00
|
9
huyujievip 2 天前
看文档是支持泛型函数指定类型 mock 的,但是自己尝试下来确不支持,求解答,谢谢
报错: panic: func not instrumented by xgo, see https://github.com/xhd2015/xgo/tree/master/doc/ERR_NOT_INSTRUMENTED.md: demo_test.MyFuncT[int] ```go package demo_test import ( "testing" "github.com/xhd2015/xgo/runtime/mock" ) func MyFunc() string { return "my func" } func MyFuncT[T any](t T) T { return t } var MyFuncTInt = MyFuncT[int] func TestFuncMock(t *testing.T) { mock.Patch(MyFunc, func() string { return "mock func" }) text := MyFunc() if text != "mock func" { t.Fatalf("expect MyFunc() to be 'mock func', actual: %s", text) } } func TestFuncMockIntA(t *testing.T) { mock.Patch(MyFuncTInt, func(t int) int { return 2 }) text := MyFuncTInt(1) if text != 2 { t.Fatalf("expect intA() to be '2', actual: %d", text) } } func TestFuncMockT(t *testing.T) { println("111111") mock.Patch(MyFuncTInt, func(t int) int { println("333333") return 2 }) println("222222") text := MyFuncTInt(1) if text != 2 { t.Fatalf("expect MyFuncT() to be '2', actual: %d", text) } } ``` ```console xgo test -v ./ === RUN TestFuncMock --- PASS: TestFuncMock (0.00s) === RUN TestFuncMockIntA --- FAIL: TestFuncMockIntA (0.00s) panic: func not instrumented by xgo, see https://github.com/xhd2015/xgo/tree/master/doc/ERR_NOT_INSTRUMENTED.md: demo_test.MyFuncT[int] [recovered] panic: func not instrumented by xgo, see https://github.com/xhd2015/xgo/tree/master/doc/ERR_NOT_INSTRUMENTED.md: demo_test.MyFuncT[int] goroutine 19 [running]: testing.tRunner.func1.2({0x100c85be0, 0x140000a0ac0}) /Users/lula/.xgo/go-instrument/go1.24.2_op_ho_Ce_go_1._li_9f53f045/go1.24.2/src/testing/testing.go:1734 +0x1ac testing.tRunner.func1() /Users/lula/.xgo/go-instrument/go1.24.2_op_ho_Ce_go_1._li_9f53f045/go1.24.2/src/testing/testing.go:1737 +0x334 panic({0x100c85be0?, 0x140000a0ac0?}) /Users/lula/.xgo/go-instrument/go1.24.2_op_ho_Ce_go_1._li_9f53f045/go1.24.2/src/runtime/panic.go:792 +0x124 github.com/xhd2015/xgo/runtime/internal/trap.Inspect({0x100c75480, 0x100cb6540}) /Users/lula/Library/Go/pkg/mod/github.com/xhd2015/xgo/[email protected]/internal/trap/inspect.go:68 +0x530 github.com/xhd2015/xgo/runtime/internal/trap.pushMockReplacer({0x100c75480, 0x100cb6540}, {0x100c75480, 0x100cb6550}) /Users/lula/Library/Go/pkg/mod/github.com/xhd2015/xgo/[email protected]/internal/trap/mock.go:160 +0x3d0 github.com/xhd2015/xgo/runtime/internal/trap.PushMockReplacer(...) /Users/lula/Library/Go/pkg/mod/github.com/xhd2015/xgo/[email protected]/internal/trap/mock.go:47 github.com/xhd2015/xgo/runtime/mock.Patch(...) /Users/lula/Library/Go/pkg/mod/github.com/xhd2015/xgo/[email protected]/mock/patch.go:15 demo_test.TestFuncMockIntA(0x14000146380) /Users/lula/Code/Go/go-learn/demo/demo_test.go:30 +0x14c testing.tRunner(0x14000146380, 0x100cb5c50) /Users/lula/.xgo/go-instrument/go1.24.2_op_ho_Ce_go_1._li_9f53f045/go1.24.2/src/testing/testing.go:1792 +0xe4 created by testing.(*T).Run in goroutine 1 /Users/lula/.xgo/go-instrument/go1.24.2_op_ho_Ce_go_1._li_9f53f045/go1.24.2/src/testing/testing.go:1851 +0x374 FAIL demo 0.259s FAIL ``` |
10
huyujievip 2 天前
第三个 Test 函数代码贴错了,纠正一下,下面的日志没有错
➜ demo xgo version 1.1.7 ➜ demo xgo exec go version go version go1.24.2 darwin/arm64 ➜ demo go env GOHOSTARCH='arm64' GOHOSTOS='darwin' GOVERSION='go1.24.2' ```go package demo_test import ( "testing" "github.com/xhd2015/xgo/runtime/mock" ) func MyFunc() string { return "my func" } func MyFuncT[T any](t T) T { return t } var MyFuncTInt = MyFuncT[int] func TestFuncMock(t *testing.T) { mock.Patch(MyFunc, func() string { return "mock func" }) text := MyFunc() if text != "mock func" { t.Fatalf("expect MyFunc() to be 'mock func', actual: %s", text) } } func TestFuncMockIntA(t *testing.T) { mock.Patch(MyFuncTInt, func(t int) int { return 2 }) text := MyFuncTInt(1) if text != 2 { t.Fatalf("expect intA() to be '2', actual: %d", text) } } func TestFuncMockT(t *testing.T) { println("111111") mock.Patch(MyFuncT[int], func(t int) int { println("333333") return 2 }) println("222222") text := MyFuncTInt(1) if text != 2 { t.Fatalf("expect MyFuncT() to be '2', actual: %d", text) } } ``` |
11
xhd2015 OP @huyujievip 感谢反馈,我今天看下这个问题。根据这个测试用例,范型是支持的 https://github.com/xhd2015/xgo/blob/master/runtime/test/mock/mock_generic/mock_generic_go1.20_above_should_success_test.go
|