testify
https://github.com/stretchr/testify
https://pkg.go.dev/github.com/stretchr/testify
https://github.com/vektra/mockery
https://blog.csdn.net/darjun/article/details/119658145
https://segmentfault.com/a/1190000040501767
https://segmentfault.com/a/1190000016897506
assert
mock 测试替身
The mock package provides a mechanism for easily writing mock objects that can be used in place of real objects when writing test code.
示例1
| $ mkdir testmodule
$ cd testmodule
$ go mod init example.com/testmodule
|
新建main.go
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | package main
type MyInterface interface {
MyAdd(x, y int) int
}
type MyCal struct{}
func (mycal *MyCal) MyAdd(x, y int) int {
return x + y
}
func TestCal(calObj MyInterface) {
calObj.MyAdd(2, 3)
calObj.MyAdd(333, 333)
}
|
新建main_test.go
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | package main
import (
"testing"
"github.com/stretchr/testify/mock"
)
type MyMockedObject struct {
mock.Mock
}
func (m *MyMockedObject) MyAdd(x, y int) int {
args := m.Called(x, y)
return args.Int(0)
}
func TestSomething(t *testing.T) {
// create an instance of our test object
testObj := new(MyMockedObject)
// setup expectations,这里只设置预期值,不会验证参数和结果的对应关系
// 这里只是去测试 TestCal,不会去测试 MyAdd
testObj.On("MyAdd", 2, 3).Return(23333)
testObj.On("MyAdd", 333, 333).Return(66666)
// call the code we are testing
TestCal(testObj)
// assert that the expectations were met
testObj.AssertExpectations(t)
}
|
| $ go get github.com/stretchr/testify/mock
$ go test
PASS
ok example.com/testmodule 0.004s
|
示例2
我们现在要编写一个从一个站点拉取用户列表信息的程序,拉取完成之后程序显示和分析。
如果每次都去访问网络会带来极大的不确定性,甚至每次返回不同的列表,这就给测试带来了极大的困难。我们可以使用 Mock 技术,让拉取都返回我们指定的结果。
新建main.go
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 | package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type User struct {
Name string
Age int
}
type ICrawler interface {
GetUserList() ([]*User, error)
}
type MyCrawler struct {
url string
}
func (c *MyCrawler) GetUserList() ([]*User, error) {
resp, err := http.Get(c.url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var userList []*User
err = json.Unmarshal(data, &userList)
if err != nil {
return nil, err
}
return userList, nil
}
func GetAndPrintUsers(crawler ICrawler) {
users, err := crawler.GetUserList()
if err != nil {
return
}
for _, u := range users {
fmt.Println(u)
}
}
|
新建main_test.go
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 | package main
import (
"testing"
"github.com/stretchr/testify/mock"
)
type MockCrawler struct {
mock.Mock
}
func (m *MockCrawler) GetUserList() ([]*User, error) {
args := m.Called()
return args.Get(0).([]*User), args.Error(1)
}
var (
MockUsers []*User
)
func init() {
MockUsers = append(MockUsers, &User{"dj", 18})
MockUsers = append(MockUsers, &User{"zhangsan", 20})
}
func TestGetUserList(t *testing.T) {
crawler := new(MockCrawler)
// 每次 GetUserList 都返回 MockUsers,
// 这里只测试 GetAndPrintUsers 这个函数,不会测试 GetUserList
// 只是在 GetAndPrintUsers 调用 GetUserList 时返回我们指定的结果
crawler.On("GetUserList").Return(MockUsers, nil)
GetAndPrintUsers(crawler)
crawler.AssertExpectations(t)
}
|
suite 测试套件
比较两个结构体
可以使用 reflect 进行比较
| if !reflect.DeepEqual(tt.want, got) {
t.Errorf("prepareData want = %v,\ngot = %v\n", tt.want, got)
}
|