Best Mock code snippet using gomock.addAction
call.go
Source:call.go
...92// It takes an interface{} argument to support n-arity functions.93func (c *Call) DoAndReturn(f interface{}) *Call {94 // TODO: Check arity and types here, rather than dying badly elsewhere.95 v := reflect.ValueOf(f)96 c.addAction(func(args []interface{}) []interface{} {97 vargs := make([]reflect.Value, len(args))98 ft := v.Type()99 for i := 0; i < len(args); i++ {100 if args[i] != nil {101 vargs[i] = reflect.ValueOf(args[i])102 } else {103 // Use the zero value for the arg.104 vargs[i] = reflect.Zero(ft.In(i))105 }106 }107 vrets := v.Call(vargs)108 rets := make([]interface{}, len(vrets))109 for i, ret := range vrets {110 rets[i] = ret.Interface()111 }112 return rets113 })114 return c115}116// Do declares the action to run when the call is matched. The function's117// return values are ignored to retain backward compatibility. To use the118// return values call DoAndReturn.119// It takes an interface{} argument to support n-arity functions.120func (c *Call) Do(f interface{}) *Call {121 // TODO: Check arity and types here, rather than dying badly elsewhere.122 v := reflect.ValueOf(f)123 c.addAction(func(args []interface{}) []interface{} {124 vargs := make([]reflect.Value, len(args))125 ft := v.Type()126 for i := 0; i < len(args); i++ {127 if args[i] != nil {128 vargs[i] = reflect.ValueOf(args[i])129 } else {130 // Use the zero value for the arg.131 vargs[i] = reflect.Zero(ft.In(i))132 }133 }134 v.Call(vargs)135 return nil136 })137 return c138}139// Return declares the values to be returned by the mocked function call.140func (c *Call) Return(rets ...interface{}) *Call {141 c.t.Helper()142 mt := c.methodType143 if len(rets) != mt.NumOut() {144 c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d [%s]",145 c.receiver, c.method, len(rets), mt.NumOut(), c.origin)146 }147 for i, ret := range rets {148 if got, want := reflect.TypeOf(ret), mt.Out(i); got == want {149 // Identical types; nothing to do.150 } else if got == nil {151 // Nil needs special handling.152 switch want.Kind() {153 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:154 // ok155 default:156 c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable [%s]",157 i, c.receiver, c.method, want, c.origin)158 }159 } else if got.AssignableTo(want) {160 // Assignable type relation. Make the assignment now so that the generated code161 // can return the values with a type assertion.162 v := reflect.New(want).Elem()163 v.Set(reflect.ValueOf(ret))164 rets[i] = v.Interface()165 } else {166 c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v [%s]",167 i, c.receiver, c.method, got, want, c.origin)168 }169 }170 c.addAction(func([]interface{}) []interface{} {171 return rets172 })173 return c174}175// Times declares the exact number of times a function call is expected to be executed.176func (c *Call) Times(n int) *Call {177 c.minCalls, c.maxCalls = n, n178 return c179}180// SetArg declares an action that will set the nth argument's value,181// indirected through a pointer. Or, in the case of a slice, SetArg182// will copy value's elements into the nth argument.183func (c *Call) SetArg(n int, value interface{}) *Call {184 c.t.Helper()185 mt := c.methodType186 // TODO: This will break on variadic methods.187 // We will need to check those at invocation time.188 if n < 0 || n >= mt.NumIn() {189 c.t.Fatalf("SetArg(%d, ...) called for a method with %d args [%s]",190 n, mt.NumIn(), c.origin)191 }192 // Permit setting argument through an interface.193 // In the interface case, we don't (nay, can't) check the type here.194 at := mt.In(n)195 switch at.Kind() {196 case reflect.Ptr:197 dt := at.Elem()198 if vt := reflect.TypeOf(value); !vt.AssignableTo(dt) {199 c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v [%s]",200 n, vt, dt, c.origin)201 }202 case reflect.Interface:203 // nothing to do204 case reflect.Slice:205 // nothing to do206 default:207 c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface non-slice type %v [%s]",208 n, at, c.origin)209 }210 c.addAction(func(args []interface{}) []interface{} {211 v := reflect.ValueOf(value)212 switch reflect.TypeOf(args[n]).Kind() {213 case reflect.Slice:214 setSlice(args[n], v)215 default:216 reflect.ValueOf(args[n]).Elem().Set(v)217 }218 return nil219 })220 return c221}222// isPreReq returns true if other is a direct or indirect prerequisite to c.223func (c *Call) isPreReq(other *Call) bool {224 for _, preReq := range c.preReqs {225 if other == preReq || preReq.isPreReq(other) {226 return true227 }228 }229 return false230}231// After declares that the call may only match after preReq has been exhausted.232func (c *Call) After(preReq *Call) *Call {233 c.t.Helper()234 if c == preReq {235 c.t.Fatalf("A call isn't allowed to be its own prerequisite")236 }237 if preReq.isPreReq(c) {238 c.t.Fatalf("Loop in call order: %v is a prerequisite to %v (possibly indirectly).", c, preReq)239 }240 c.preReqs = append(c.preReqs, preReq)241 return c242}243// Returns true if the minimum number of calls have been made.244func (c *Call) satisfied() bool {245 return c.numCalls >= c.minCalls246}247// Returns true iff the maximum number of calls have been made.248func (c *Call) exhausted() bool {249 return c.numCalls >= c.maxCalls250}251func (c *Call) String() string {252 args := make([]string, len(c.args))253 for i, arg := range c.args {254 args[i] = arg.String()255 }256 arguments := strings.Join(args, ", ")257 return fmt.Sprintf("%T.%v(%s) %s", c.receiver, c.method, arguments, c.origin)258}259// Tests if the given call matches the expected call.260// If yes, returns nil. If no, returns error with message explaining why it does not match.261func (c *Call) matches(args []interface{}) error {262 if !c.methodType.IsVariadic() {263 if len(args) != len(c.args) {264 return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: %d",265 c.origin, len(args), len(c.args))266 }267 for i, m := range c.args {268 if !m.Matches(args[i]) {269 return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v",270 c.origin, strconv.Itoa(i), args[i], m)271 }272 }273 } else {274 if len(c.args) < c.methodType.NumIn()-1 {275 return fmt.Errorf("Expected call at %s has the wrong number of matchers. Got: %d, want: %d",276 c.origin, len(c.args), c.methodType.NumIn()-1)277 }278 if len(c.args) != c.methodType.NumIn() && len(args) != len(c.args) {279 return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: %d",280 c.origin, len(args), len(c.args))281 }282 if len(args) < len(c.args)-1 {283 return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: greater than or equal to %d",284 c.origin, len(args), len(c.args)-1)285 }286 for i, m := range c.args {287 if i < c.methodType.NumIn()-1 {288 // Non-variadic args289 if !m.Matches(args[i]) {290 return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v",291 c.origin, strconv.Itoa(i), args[i], m)292 }293 continue294 }295 // The last arg has a possibility of a variadic argument, so let it branch296 // sample: Foo(a int, b int, c ...int)297 if i < len(c.args) && i < len(args) {298 if m.Matches(args[i]) {299 // Got Foo(a, b, c) want Foo(matcherA, matcherB, gomock.Any())300 // Got Foo(a, b, c) want Foo(matcherA, matcherB, someSliceMatcher)301 // Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC)302 // Got Foo(a, b) want Foo(matcherA, matcherB)303 // Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD)304 continue305 }306 }307 // The number of actual args don't match the number of matchers,308 // or the last matcher is a slice and the last arg is not.309 // If this function still matches it is because the last matcher310 // matches all the remaining arguments or the lack of any.311 // Convert the remaining arguments, if any, into a slice of the312 // expected type.313 vargsType := c.methodType.In(c.methodType.NumIn() - 1)314 vargs := reflect.MakeSlice(vargsType, 0, len(args)-i)315 for _, arg := range args[i:] {316 vargs = reflect.Append(vargs, reflect.ValueOf(arg))317 }318 if m.Matches(vargs.Interface()) {319 // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, gomock.Any())320 // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, someSliceMatcher)321 // Got Foo(a, b) want Foo(matcherA, matcherB, gomock.Any())322 // Got Foo(a, b) want Foo(matcherA, matcherB, someEmptySliceMatcher)323 break324 }325 // Wrong number of matchers or not match. Fail.326 // Got Foo(a, b) want Foo(matcherA, matcherB, matcherC, matcherD)327 // Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC, matcherD)328 // Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD, matcherE)329 // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, matcherC, matcherD)330 // Got Foo(a, b, c) want Foo(matcherA, matcherB)331 return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v",332 c.origin, strconv.Itoa(i), args[i:], c.args[i])333 }334 }335 // Check that all prerequisite calls have been satisfied.336 for _, preReqCall := range c.preReqs {337 if !preReqCall.satisfied() {338 return fmt.Errorf("Expected call at %s doesn't have a prerequisite call satisfied:\n%v\nshould be called before:\n%v",339 c.origin, preReqCall, c)340 }341 }342 // Check that the call is not exhausted.343 if c.exhausted() {344 return fmt.Errorf("Expected call at %s has already been called the max number of times.", c.origin)345 }346 return nil347}348// dropPrereqs tells the expected Call to not re-check prerequisite calls any349// longer, and to return its current set.350func (c *Call) dropPrereqs() (preReqs []*Call) {351 preReqs = c.preReqs352 c.preReqs = nil353 return354}355func (c *Call) call(args []interface{}) []func([]interface{}) []interface{} {356 c.numCalls++357 return c.actions358}359// InOrder declares that the given calls should occur in order.360func InOrder(calls ...*Call) {361 for i := 1; i < len(calls); i++ {362 calls[i].After(calls[i-1])363 }364}365func setSlice(arg interface{}, v reflect.Value) {366 va := reflect.ValueOf(arg)367 for i := 0; i < v.Len(); i++ {368 va.Index(i).Set(v.Index(i))369 }370}371func (c *Call) addAction(action func([]interface{}) []interface{}) {372 c.actions = append(c.actions, action)373}...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!