前言
- 当我们完成一个模块后,先不着急继续完成其他模块,而是进行单元测试,这样我们能够提前发现当前模块的错误,减少整个项目完成后出现的bug。
- 可以了解下TDD(测试驱动开发)
1.需要的包
1.常用的包
import (
//gomonkey : 一个方便的打桩工具
"github.com/agiledragon/gomonkey"
//testify : 一个方便的断言工具 (最新版本不支持go 1.12,推荐降低版本)
"github.com/stretchr/testify/assert"
)
2.补充包
import (
//模拟redis
"github.com/alicebob/miniredis/v2"
//模拟sqlmock
"github.com/DATA-DOG/go-sqlmock"
)
2.外部调用模块
1.person.go
package unittesting
func Eat(s string,t bool) bool {
return true
}
2.user.go
package unittesting
func Add() bool {
//调用外部func
result := Eat("eat",true)
return result
}
3.单元测试
package unittesting
import (
"github.com/agiledragon/gomonkey"
"github.com/stretchr/testify/assert"
"testing"
)
func TestUser(t *testing.T) {
t.Run("测试:外部func调用失败",t, func(t *testing.T) {
//打桩:外部func
gomonkey.ApplyFunc := gomonkey.ApplyFunc(Eat, func(_ string, _ bool) bool {
return false //模拟值
})
defer applyFunc.Reset() //如果不重置,后面调用该模块桩的结果不变
//执行
actual := Add()
//断言 expect --- actual
assert.Equal(t,false,actual)
})
}
3.外部方法模块 (为一个方法打桩)
1. person.go (method)
package unittesting
type Person struct {
name string
}
func (p *Person) Play(s string,t bool) error {
return nil
}
2.user.go
package unittesting
func Add() error {
person := Person{
name: "Tom",
}
//调用外部method
err := person.Play("", false)
return err
}
3.user_test.go
package unittesting
import (
"errors"
"github.com/agiledragon/gomonkey"
"github.com/stretchr/testify/assert"
"reflect"
"testing"
)
func TestUser(t *testing.T) {
t.Run("测试:外部method调用err",t, func(t *testing.T) {
var p *Person //注意
//打桩:method
gomonkey.ApplyMethod := gomonkey.ApplyMethod(reflect.TypeOf(p), "Play", func(_ *Person, _ string, _ bool) error {
return errors.New("test Err")
})
defer applyMethod.Reset() //如果不重置,后面调用该模块桩的结果不变
//执行
actualErr := Add()
//断言 expect --- actual
assert.Equal(t,"test Err",actualErr.Error())
})
}
可能会出现的问题
使用gomonkey进行测试时,进行了打桩,但桩失效(在进行断点测试的时候能够成功
问题原因
对内联函数的Stub,go test命令行一定要加上参数才可生效。
解决方案
命令行默认加上-gcflags=all=-l就行了
方法1(推荐使用)
//在测试包内打命令
go test -gcflags "all=-l"
方法2(不推荐使用–无法进行断点测试)
设置goland
Run->Edit Configurations ->Go Test-> Go tool arguments ->设置 -gcflags “all=-l”