How to use addAction method of gomock Package

Best Mock code snippet using gomock.addAction

call.go

Source:call.go Github

copy

Full Screen

...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}...

Full Screen

Full Screen

Automation Testing Tutorials

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.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful