write testable codes!
当一个团队合做一个项目时,必然会涉及到接口的调用,这时假若你的上下游团队成员还未写好接口,可是又要测试本身的代码,mock即可派上用场。mock出的对象能模拟接口的行为,给出预期的结果,好比一个远程调用接口mock后能够在本机调用并马上返回预设的结果。git
1 . go get github.com/golang/mock/
2 . 在/mock/mockgen目录下执行go build命令生成二进制可执行文件mockgen,并放置PATH环境变量所在目录下github
0 . 目录结构:golang
project . └── service └── mocks └── service_mock.go └── service.go └── todo └── exec.go └── exec_test.go
1 . 编写接口文件/service/service.go工具
package service type Request struct { Id int } type Reply struct { Res string } type IService interface { CallTest(req *Request) (*Reply, error) }
2 . 在service目录下执行命令:mockgen -destination ./mocks/service_mock.go -package mocks -source ./service.go
测试
3 . 编写逻辑层文件/todo/exec.goui
package todo import ( "fmt" "project/service" ) type Client struct { service.IService } func (c *Client) Todo(req *service.Request) error { reply, err := c.CallTest(req) if err != nil { return err } fmt.Printf("req_id is %v and reply_res is %v\n:", req.Id, reply.Res) return nil }
4.编写测试文件/todo/exec_test.gocode
package todo import ( "errors" "github.com/golang/mock/gomock" "project/service" "project/service/mocks" "testing" ) func TestTodo(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mocks.NewMockIService(ctrl) req := &service.Request{Id: 10088} reply := &service.Reply{Res: "您好,这里是中国行动,充值请按1,其余请挂机~"} errNil := errors.New("你拨打的电话是空号!") tests := []struct { req *service.Request expectErr error }{ {req: req, expectErr: nil}, {req: nil, expectErr: errNil}, } mock.EXPECT().CallTest(req).Return(reply, nil) mock.EXPECT().CallTest(nil).Return(nil, errNil) c := &Client{IService: mock} for i, v := range tests { err := c.Todo(v.req) if err != v.expectErr { t.Errorf("test %v:get wrong expectErr %v and expectErr is %v", i, err, v.expectErr) } } }
5 . 在todo目录下执行go test查看结果
参考连接:https://github.com/golang/mock/blob/master/README.md对象