Documentation
¶
Overview ¶
Package genmock is a core of the mock system. You can use it as is (see ExampleMock) to mock any your object, but it is better to use the generator of the test objects. If you will be use generator you can handle errors of argument types in compile code stage instead panic in runtime. This mock returns error instead of panic, so you can handle error and stop you tests correctly.
Example ¶
Example of using the generated code with mock interface.
package main import ( "fmt" "log" "gitlab.com/so_literate/genmock" ) // Example of using the generated code with mock interface. func main() { iface := NewIface_Mock(genmock.NewLoggerHelper(log.Default())) // Pass *testing.T here. iface.ReturnMockErrorAsResult = true // You can enable returning mock error as result of the method. // Create and set argument and return parameters of the method. iface.On_Method().Args(1).Rets(nil).Times(genmock.TimesAny) err := iface.Method(1) // Call the method. fmt.Println(err) err = iface.Mock.AssertExpectations() // Check that all method called. fmt.Println(err) } // Iface_Mock implements mock of the Iface interface. type Iface_Mock struct { Mock *genmock.Mock t genmock.TestingT ReturnMockErrorAsResult bool } // NewIface_Mock returns a new mock of Iface interface implementer. // Takes *testing.T to stop failed testing process. func NewIface_Mock(t genmock.TestingT) *Iface_Mock { return &Iface_Mock{ Mock: genmock.NewMock(), t: t, } } func (_m *Iface_Mock) Method(i int64) error { _ret, _err := _m.Mock.MethodCalled("Method", i) if _err != nil { if _m.ReturnMockErrorAsResult { return fmt.Errorf("(Method) call mock method: %w", _err) } _m.t.Fatalf("(Method) call mock method: %s", _err) } if len(_ret) != 1 { _err = fmt.Errorf("%w: want 1, got %d", genmock.ErrWrongReturnedLenght, len(_ret)) if _m.ReturnMockErrorAsResult { return fmt.Errorf("(Method) check length of returned params: %w", _err) } _m.t.Fatalf("(Method) check length of returned params: %s", _err) } var _r0 error if _r := _ret[0]; _r != nil { if _v, _ok := _r.(error); _ok { _r0 = _v } else { _err = fmt.Errorf("%w [ret #0]: want 'error', got: %[2]T(%#[2]v)", genmock.ErrUnexpectedArgumentType, _r) if _m.ReturnMockErrorAsResult { return fmt.Errorf("(Method) check returned type: %w", _err) } _m.t.Fatalf("(Method) check returned type: %s", _err) } } return _r0 } // Iface_MockSet_Method allows to set arguments and results of the mock call Method. type Iface_MockSet_Method struct { Call *genmock.Call } // On_Method adds a call of the Method to mock. func (_m *Iface_Mock) On_Method() Iface_MockSet_Method { call := genmock.NewCall( "Method", []interface{}{genmock.AnythingOfType("int64")}, []interface{}{nil}, 1, ) _m.Mock.AddCall(call) return Iface_MockSet_Method{Call: call} } // Args sets the exact values of the arguments. func (_s Iface_MockSet_Method) Args(i int64) Iface_MockSet_Method { _s.Call.Args[0] = i return _s } // ArgsAnything sets the interface values of the arguments. func (_s Iface_MockSet_Method) ArgsAnything(i interface{}) Iface_MockSet_Method { _s.Call.Args[0] = i return _s } // Arg_i_Matcher sets matcher of the i argument value. func (_s Iface_MockSet_Method) Arg_i_Matcher(matcher func(i int64) bool) Iface_MockSet_Method { realMatcher := func(arg interface{}) bool { value, ok := arg.(int64) if !ok { return false } return matcher(value) } _s.Call.Args[0] = realMatcher return _s } // Rets sets the exact values of the result parameters. func (_s Iface_MockSet_Method) Rets(_r0 error) Iface_MockSet_Method { _s.Call.Returns[0] = _r0 return _s } // Times sets number of times to call this caller of the method. func (_s Iface_MockSet_Method) Times(times int) Iface_MockSet_Method { _s.Call.Times = times return _s }
Output: <nil> <nil>
Example (WithoutCodeGen) ¶
package main import ( "fmt" "log" "time" "gitlab.com/so_literate/genmock" ) // Data in the database. type Data struct { ID int Data string } // DB describes methods of the real object. type DB interface { SetData(data *Data) error GetData(id int64) (*Data, error) Clean() } // DBMock your own type that implements DB interface. type DBMock struct { mock *genmock.Mock t genmock.TestingT // you can pass there a (t *testing.T). } func (db *DBMock) SetData(data *Data) error { db.t.Helper() ret, err := db.mock.MethodCalled("SetData", data) if err != nil { db.t.Fatalf("db.MethodCalled: %s", err) } res, err := genmock.ConvertArgError(0, ret) if err != nil { db.t.Fatalf("genmock.ConvertArgError (SetData): %s", err) } return res } func (db *DBMock) GetData(id int64) (*Data, error) { db.t.Helper() ret, err := db.mock.MethodCalled("GetData", id) if err != nil { db.t.Fatalf("db.MethodCalled: %s", err) } data, ok := ret[0].(*Data) if !ok { db.t.Fatalf("wrong type of the return argument: %#v", ret[0]) } resErr, err := genmock.ConvertArgError(1, ret) if err != nil { db.t.Fatalf("genmock.ConvertArgError (GetData): %s", err) } return data, resErr } func (db *DBMock) Clean() { db.t.Helper() _, err := db.mock.MethodCalled("Clean") if err != nil { db.t.Fatalf("db.MethodCalled: %s", err) } } // dbCodeUser code that uses DB interface. func dbCodeUser(db DB) (*Data, error) { err := db.SetData(&Data{Data: "some text"}) if err != nil { return nil, fmt.Errorf("db.SetData: %w", err) } data, err := db.GetData(1) if err != nil { return nil, fmt.Errorf("db.GetData: %w", err) } db.Clean() return data, nil } func main() { mock := genmock.NewMock() matcher := func(arg interface{}) bool { data := arg.(*Data) return data.Data != "" } mock. AddCall(genmock.NewCall( "SetData", []interface{}{matcher}, // First argument with custom compare. []interface{}{error(nil)}, // Return nil as error. genmock.TimesAny, // You can call it any times. )). AddCall(genmock.NewCall( "GetData", []interface{}{genmock.AnythingOfType("int64")}, // First argument with soft compare by type only. []interface{}{&Data{Data: "text"}, nil}, // Returns data and nil as error. 1, // You can call it only 1 time. )) cleanCall := genmock.NewCall("Clean", nil, nil, 1) cleanCall.WaitTime = time.Millisecond * 10 // Wait 10 millisecond when mock found this call. mock.AddCall(cleanCall) db := &DBMock{ mock: mock, t: genmock.NewLoggerHelper(log.Default()), // pass *testing.T here. } data, err := dbCodeUser(db) if err != nil { fmt.Println(err) return } err = db.mock.AssertExpectations() // Check that all method was called. fmt.Println(data.Data) fmt.Println(err) }
Output: text <nil>
Index ¶
- Constants
- Variables
- func ConvertArgBool(index int, args []interface{}) (bool, error)
- func ConvertArgError(index int, args []interface{}) (res, err error)
- func ConvertArgInt(index int, args []interface{}) (int, error)
- func ConvertArgInt16(index int, args []interface{}) (int16, error)
- func ConvertArgInt32(index int, args []interface{}) (int32, error)
- func ConvertArgInt64(index int, args []interface{}) (int64, error)
- func ConvertArgInt8(index int, args []interface{}) (int8, error)
- func ConvertArgString(index int, args []interface{}) (string, error)
- func ConvertArgUint(index int, args []interface{}) (uint, error)
- func ConvertArgUint16(index int, args []interface{}) (uint16, error)
- func ConvertArgUint32(index int, args []interface{}) (uint32, error)
- func ConvertArgUint64(index int, args []interface{}) (uint64, error)
- func ConvertArgUint8(index int, args []interface{}) (uint8, error)
- func IsArgumentListsEquals(expArgs, actualArgs []interface{}) error
- func IsArgumentListsSimilar(expArgs, actualArgs []interface{}) error
- func IsArgumentsEquals(expArg, actualArg interface{}) error
- func IsArgumentsSimilar(expArg, actualArg interface{}) error
- type AnythingArg
- type AnythingOfTypeArg
- type Call
- type IsEqual
- type Mock
- type TestingT
Examples ¶
Constants ¶
const Anything = AnythingArg("Anything")
Anything is a const to pass in expected argument value.
genmock.NewCall("MethodName", []interface{}{genmock.Anything}, nil, 1)
const TimesAny int = -1
TimesAny means that the method can be called any number of times.
Variables ¶
var ( // ErrMethodUnknown returns when method do not have registered calls. ErrMethodUnknown = errors.New("method unknown") // ErrLengthNotEqual returns in comparison of the arguments and the length of their different. ErrLengthNotEqual = errors.New("length is not equal") // ErrIsEqualNotTrue returns when custom matcher IsEqual returned false. ErrIsEqualNotTrue = errors.New("matcher IsEqual is not true") // ErrDeepEqualNotTrue returns when reflect.DeepEqual comparison retruned false. ErrDeepEqualNotTrue = errors.New("deep equal is not true") // ErrArgumentTypeUnknown returns when you used AnythingOfType as an argument // and reflect.TypeOf can't to got type of the argument. ErrArgumentTypeUnknown = errors.New("type of the argument unknown") // ErrUnexpectedArgumentType returns when you used AnythingOfType as an argument // and type of the actual argument is different. ErrUnexpectedArgumentType = errors.New("type of the argument is unexpected") // ErrExpectedCallNotFound returns when expected call of the method not found. // Maybe you used Anything or AnythingOfType or you just got wrong values of the actual arguments. ErrExpectedCallNotFound = errors.New("expected call not found") // ErrSimilarCallNotFound returns when mock can't to found even similar call of the method. // Mock checked all calls with Anything/AnythingOfType arguments but nothing. ErrSimilarCallNotFound = errors.New("similar call not found") // ErrRemainsSeveralTimesCallMethods returns when you mock has // mathods to call but nobody call them. ErrRemainsSeveralTimesCallMethods = errors.New("it remains several times to call method(s)") // ErrIndexOutOfRange returns in converting type methods to avoid panic. ErrIndexOutOfRange = errors.New("index out of range") // ErrWrongReturnedLenght returns when list of the result arguments have an unexpected length. ErrWrongReturnedLenght = errors.New("length of the returned params is wrong") )
Functions ¶
func ConvertArgBool ¶
ConvertArgBool converts interface argument by index to bool type.
func ConvertArgError ¶
ConvertArgError converts interface argument by index to error type.
func ConvertArgInt ¶
ConvertArgInt converts interface argument by index to int type.
func ConvertArgInt16 ¶
ConvertArgInt16 converts interface argument by index to int16 type.
func ConvertArgInt32 ¶
ConvertArgInt32 converts interface argument by index to int32 type.
func ConvertArgInt64 ¶
ConvertArgInt64 converts interface argument by index to int64 type.
func ConvertArgInt8 ¶
ConvertArgInt8 converts interface argument by index to int8 type.
func ConvertArgString ¶
ConvertArgString converts interface argument by index to string type.
func ConvertArgUint ¶
ConvertArgUint converts interface argument by index to uint type.
func ConvertArgUint16 ¶
ConvertArgUint16 converts interface argument by index to uint16 type.
func ConvertArgUint32 ¶
ConvertArgUint32 converts interface argument by index to uint32 type.
func ConvertArgUint64 ¶
ConvertArgUint64 converts interface argument by index to uint64 type.
func ConvertArgUint8 ¶
ConvertArgUint8 converts interface argument by index to uint8 type.
func IsArgumentListsEquals ¶
func IsArgumentListsEquals(expArgs, actualArgs []interface{}) error
IsArgumentListsEquals compares two lists of the arguments. Arguments should be equal by type and value.
func IsArgumentListsSimilar ¶
func IsArgumentListsSimilar(expArgs, actualArgs []interface{}) error
IsArgumentListsSimilar compare two lists of the arguments. Arguments may contains less accurate comparison types (Anything, AnythingOfType).
func IsArgumentsEquals ¶
func IsArgumentsEquals(expArg, actualArg interface{}) error
IsArgumentsEquals checks arguments they are should be equal or expected argument should be matcher function.
func IsArgumentsSimilar ¶
func IsArgumentsSimilar(expArg, actualArg interface{}) error
IsArgumentsSimilar compares arguments they are may be Anything, AnythingOfType or equal by type and value.
Types ¶
type AnythingArg ¶
type AnythingArg string
AnythingArg argument of the method may be any of type and value.
type AnythingOfTypeArg ¶
type AnythingOfTypeArg string
AnythingOfTypeArg argument of the method may be any of value but with mane of type.
func AnythingOfType ¶
func AnythingOfType(typeName string) AnythingOfTypeArg
AnythingOfType is a func to wrap type name to use as expected argument in method.
genmock.NewCall("MethodName", []interface{}{genmock.AnythingOfType("int")}, nil, 1)
type Call ¶
type Call struct { // Name of the method. MethodName string // Arguments of the method to compare with called actual arguments. Args []interface{} // Arguments of the method to retun when mock found this method call. Returns []interface{} // The number of times to call this caller of the method. // -1 any times, 0 already called, 1 ... n times. Times int // Call will be block until it receives a message or is closed. WaitFor <-chan time.Time // Call will be sleep this time before return arguments. WaitTime time.Duration // Runs func RunFn(args) when mock found this method call. // It's useful when you want to unmarshall method arguments. RunFn func(args []interface{}) // Calls panic(*PanicMessage) when mock found this method call. PanicMsg *string }
Call way to call method, contains expected arguments, number of calls and other results of the call. You can set differents expected arguments per call or you can set univarsal set of the arguments.
type IsEqual ¶
type IsEqual func(interface{}) bool
IsEqual it is type just for documentation. You can use this function to compare arguments according to your own rules.
matcher := func(arg interface{}) bool { return arg.(int) == 3 } genmock.NewCall("MethodName", []interface{}{matcher}, nil, 1)
type Mock ¶
type Mock struct {
// contains filtered or unexported fields
}
Mock contains methods to add and call mocked interface methods.
func NewMock ¶
func NewMock() *Mock
NewMock returns empty mock type. Feel free user default value of the Mock:
mock := genmock.NewMock() mock := new(genmock.Mock)
func (*Mock) AddCall ¶
AddCall adds your expected call variant of method to list of methods.
mock := genmock.NewMock().AddCall(mockMethod1).AddCall(mockMethod2)
func (*Mock) AssertExpectations ¶
AssertExpectations checks that all added methods was called or with TimesAny parameter. Returns an error with a full description of not called methods.
func (*Mock) MethodCalled ¶
MethodCalled tries to find method by name and actual arguments. First of all trying to find call with full equals arguments. If failed then trying to find similar call with Anything and AnythingOfType args. Returns the returned arguments and checks another call fields and calls them before returning the arguments.
// Method of the interface SetData(data sting) error setData := genmock.NewCall("SetData", []interface{}{genmock.AnythingOfType("string")}, []interface{}{nil}, 1) mock := genmock.NewMock().AddCall(setData) ret, err := mock.MethodCalled("SetData", "some text data")
type TestingT ¶
type TestingT interface { Fatalf(format string, args ...interface{}) Helper() }
TestingT interface for genereted mock type to pass *testing.T.
func NewLoggerHelper ¶
func NewLoggerHelper(f fatalfer) TestingT
NewLoggerHelper returns TestingT implemetner to pass logger instead *testing.T.
Directories
¶
Path | Synopsis |
---|---|
_example
|
|
codegen/mock
Package mock contains mock implementer of the Database interface.
|
Package mock contains mock implementer of the Database interface. |
cmd
|
|
genmock
Module
|