Go单测

目录

Go单测框架

Go Mock

Go Mock 的核心原理就是通过将原始代码中的接口调用替换为 mock 对象,并在测试中对 mock 对象进行合适的设定和断言,从而实现对代码的全面测试。

go get github.com/golang/mock/gomock
go get github.com/golang/mock/mockgen   //--可以在写好interface之后把桩代码生成

使用时生成桩代码的命令

//go:generate mockgen -destination=./mock_human.go  -source=interface.go
//需要将该行命令写在欲生成桩代码的接口上方(注意等号两边不要有空格)    mock_human.go会把该接口实现

运行完上述命令后,会在mock包下生成mock_human实现类

编写mock_human_test.go代码

func Test_mock_human(t *testing.T) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	mockHuman := NewMockHuman(ctrl)
	mockHuman.EXPECT().Speak().DoAndReturn(func() string {
		return "Hello0000000"
	}) //期望的返回结果

	outPut := mockHuman.Speak() //调用mock后的方法
    t.Errorf("output: %s", output)
}

此外,Go Mock还可以针对方法的调用次数做出个性化设置,最多调用次数,最少调用次数,只能调用次数,调用任意次。

Go Monkey

go monkey相比于go mock来说就十分简单粗暴,go monkey通过直接修改方法的内存空间,实现桩代码替换。这也就意味着,它可以强行给任意方法(面向对象)或函数(面向过程)打桩。

对方法打桩

type Boy struct {
}

func (b *Boy) Speak() string {
	return "Hello"
}

func Test_gomonkey(t *testing.T) {
	b := Boy{}

	patchs := gomonkey.ApplyMethod(reflect.TypeOf(&Boy{}), "Speak", func(b *Boy) string {
		return "Bye"
	})
    
	defer patchs.Reset()
	t.Errorf("Speak: %s", b.Speak())
}
运行结果
gomonkey_test.go:24: Speak: Hello   
原本的逻辑被替换

对函数打桩

func Laugh() string {
	return "ahahaha"
}

func Test_gomonkey(t *testing.T) {

	patch := gomonkey.ApplyFunc(Laugh, func() string {
		return "lol"
	})

	defer patch.Reset()
	t.Errorf("Laugh: %s", Laugh())
}

PS: 过于简单的函数go编译器会进行直接内联(inline),所以打桩会失效,因此在执行test时需要关闭内联

go test -v -gcflags=-l gomonkey_test.go
取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦