stretchr/testify · error

cannot use Func in expectations. Use mock.AnythingOfType("%T

Error message

cannot use Func in expectations. Use mock.AnythingOfType("%T")

What it means

Panicked by Call.Unset() (mock/mock.go:221) when any of the Call's recorded Arguments is a reflect.Func. Unset removes handlers by matching static argument values via Arguments.Diff; func values cannot be reliably matched this way, so testify refuses. The guard iterates c.Arguments and checks reflect.ValueOf(arg).Kind() == reflect.Func (mock/mock.go:224-227).

Source

Thrown at mock/mock.go:226

	return c.Parent.On(methodName, arguments...)
}

// Unset removes all mock handlers that satisfy the call instance arguments from being
// called. Only supported on call instances with static input arguments.
//
// For example, the only handler remaining after the following would be "MyMethod(2, 2)":
//
//	Mock.
//	   On("MyMethod", 2, 2).Return(0).
//	   On("MyMethod", 3, 3).Return(0).
//	   On("MyMethod", Anything, Anything).Return(0)
//	Mock.On("MyMethod", 3, 3).Unset()
func (c *Call) Unset() *Call {
	var unlockOnce sync.Once

	for _, arg := range c.Arguments {
		if v := reflect.ValueOf(arg); v.Kind() == reflect.Func {
			panic(fmt.Sprintf("cannot use Func in expectations. Use mock.AnythingOfType(\"%T\")", arg))
		}
	}

	c.lock()
	defer unlockOnce.Do(c.unlock)

	foundMatchingCall := false

	// in-place filter slice for calls to be removed - iterate from 0'th to last skipping unnecessary ones
	var index int // write index
	for _, call := range c.Parent.ExpectedCalls {
		if call.Method == c.Method {
			_, diffCount := call.Arguments.Diff(c.Arguments)
			if diffCount == 0 {
				foundMatchingCall = true
				// Remove from ExpectedCalls - just skip it
				continue
			}

View on GitHub (pinned to 001eb7946b)

Solutions

  1. Use static (non-func) argument values in the Mock.On call so Unset can match them deterministically.
  2. Use mock.AnythingOfType("func()") instead of passing the func directly, then Unset works against the type matcher.
  3. If you only need to clear all expectations, call Mock.Mock.ExpectedCalls = nil or re-create the Mock instead of Unset.

Example fix

// before
m.On("Run", func() {}).Return(nil).Unset() // panic
// after
m.On("Run", mock.AnythingOfType("func()")).Return(nil)
Defensive patterns

Strategy: type-guard

Validate before calling

func hasFuncArg(args []interface{}) bool {
    for _, a := range args {
        if reflect.ValueOf(a).Kind() == reflect.Func { return true }
    }
    return false
}
// before .Unset(): assert.False(t, hasFuncArg(call.Arguments))

Type guard

func argsContainFunc(args []interface{}) bool {
    for _, a := range args {
        if reflect.ValueOf(a).Kind() == reflect.Func { return true }
    }
    return false
}

Try / catch

// Skip Unset when a func argument is present:
if !argsContainFunc(call.Arguments) {
    call.Unset()
}

Prevention

When it happens

Trigger: Calling Mock.On("Method", someFunc).Return(...).Unset() — i.e. trying to remove an expectation whose arguments include a function value. Also when an argument was registered with mock.MatchedBy (which wraps a func) and you later Unset.

Common situations: Test teardown that tries to remove a previously-set expectation which used a func matcher; refactoring tests to use is-functional-argument matchers without updating the Unset call.

Related errors


AI-assisted analysis of stretchr/testify@001eb7946b (2026-08-04). Data as JSON: /data/errors/f54d7c1c626d395c.json. Report an issue: GitHub.