This demo shows how rewrite and mock works.
Run:
go run github.com/xhd2015/go-mock run ./
Output:
main begin
calling: github.com/xhd2015/go-mock/example/demo/biz.Run
mock biz.Run
calling: github.com/xhd2015/go-mock/example/demo/biz.Status.Run
biz.Status.Run: 2
In biz/biz.go we defined 2 functions, one for package-level and the other for a named type:
package biz
func Run(ctx context.Context, status int, _ string) (int, error) {
fmt.Printf("biz.Run: %v\n", status)
return 0, nil
}
type Status int
func (c Status) Run(ctx context.Context, status int, _ string) (int, error) {
fmt.Printf("biz.Status.Run: %v\n", status)
return 0, nil
}
In main.go we make call to these 2 functions defiend in biz/biz.go, with just some mock setup:
package main
import (
"context"
"fmt"
"github.com/xhd2015/go-mock/example/demo/biz"
mock_biz "github.com/xhd2015/go-mock/example/demo/test/mock_gen/biz"
"github.com/xhd2015/go-mock/mock"
)
func main() {
fmt.Printf("main begin\n")
// add general function interceptor
mock.AddInterceptor(func(ctx context.Context, stubInfo *mock.StubInfo, inst, req, resp interface{}, f mock.Filter, next func(ctx context.Context) error) error {
fmt.Printf("calling: %v\n", stubInfo)
return next(ctx)
})
// associate mock into ctx
ctx := context.Background()
ctx = mock_biz.Setup(ctx, func(m *mock_biz.M) {
m.Run = func(ctx context.Context, status int, _ string) (int, error) {
fmt.Printf("mock biz.Run\n")
return 123456, nil
}
})
// call biz.Run
biz.Run(ctx, 1, "A")
// call biz.Status.Run
status := biz.Status(1)
status.Run(ctx, 2, "B")
}
We get the following output explained:
main begin --> main begin
calling: github.com/xhd2015/go-mock/example/demo/biz.Run --> printed by our general interceptor
mock biz.Run --> function mocked
calling: github.com/xhd2015/go-mock/example/demo/biz.Status.Run --> printed by our general interceptor
biz.Status.Run: 2 --> function not mocked
The interceptor is very powerful, just like interceptor in usual RCP frameworks like gRPC
. By adding interceptor we can do things in a generalized way, this would amazingly change the game of mock.
You can verify the generated content via:
go run github.com/xhd2015/go-mock print ./biz/biz.go
Original content:
package biz
import (
"context"
"fmt"
)
func Run(ctx context.Context, status int, _ string) (int, error) {
fmt.Printf("biz.Run: %v\n", status)
return 0, nil
}
type Status int
func (c Status) Run(ctx context.Context, status int, _ string) (int, error) {
fmt.Printf("biz.Status.Run: %v\n", status)
return 0, nil
}
Output: rewrite content
// rewrite of /Users/x/gopath/src/github.com/xhd2015/go-mock/example/demo/biz/biz.go:
package biz;import _mock "github.com/xhd2015/go-mock/mock"
import (
"context"
"fmt"
)
func Run(ctx context.Context, status int, unused_2 string) (Resp_0 int, err error) {var _mockreq = struct{Status int `json:"status"`;Unused_2 string `json:"unused_2"`;}{Status: status,Unused_2: unused_2};var _mockresp struct{Resp_0 int `json:"Resp_0"`;};err = _mock.TrapFunc(ctx,&_mock.StubInfo{PkgName:"github.com/xhd2015/go-mock/example/demo/biz",Owner:"",OwnerPtr:false,Name:"Run"}, nil, &_mockreq, &_mockresp,_mockRun,false,true,true);Resp_0 = _mockresp.Resp_0;return;}; func _mockRun(ctx context.Context, status int, _ string)(int, error){
fmt.Printf("biz.Run: %v\n", status)
return 0, nil
}
type Status int
func (c Status) Run(ctx context.Context, status int, unused_2 string) (Resp_0 int, err error) {var _mockreq = struct{Status int `json:"status"`;Unused_2 string `json:"unused_2"`;}{Status: status,Unused_2: unused_2};var _mockresp struct{Resp_0 int `json:"Resp_0"`;};err = _mock.TrapFunc(ctx,&_mock.StubInfo{PkgName:"github.com/xhd2015/go-mock/example/demo/biz",Owner:"Status",OwnerPtr:false,Name:"Run"}, c, &_mockreq, &_mockresp,_mockStatus_Run,true,true,true);Resp_0 = _mockresp.Resp_0;return;}; func _mockStatus_Run(c Status,ctx context.Context, status int, _ string)(int, error){
fmt.Printf("biz.Status.Run: %v\n", status)
return 0, nil
}
type-safe mock stub:
// mock of /Users/x/gopath/src/github.com/xhd2015/go-mock/example/demo/biz/biz.go:
// Code generated by go-mock; DO NOT EDIT.
package biz
import (
"context"
"github.com/xhd2015/go-mock/example/demo/biz"
_mock "github.com/xhd2015/go-mock/mock"
)
const _SKIP_MOCK = true
const FULL_PKG_NAME = "github.com/xhd2015/go-mock/example/demo/biz"
func Setup(ctx context.Context,setup func(m *M)) context.Context {
m:=M{}
setup(&m)
return _mock.WithMockSetup(ctx,FULL_PKG_NAME,m)
}
type M struct {
Run func(ctx context.Context, status int, _ string)(int, error)
Status struct{
Run func(c biz.Status,ctx context.Context, status int, _ string)(int, error)
}
}
/* prodives quick link */
var _ = func() { type Pair [2]interface{};e:=M{};_ = map[string]interface{}{
"Run": Pair{e.Run,biz.Run},
"Status":map[string]interface{}{
"Run": Pair{e.Status.Run,((*biz.Status)(nil)).Run},
},
}}