testify icon indicating copy to clipboard operation
testify copied to clipboard

mock.AnythingOfType("[]byte") doesn't quite work

Open kjlubick opened this issue 8 years ago • 11 comments

func (m *mockObj) SetFileContents(path string, contents []byte) error {
	args := m.Called(path, contents)
	return args.Error(0)
}

// in testing
m := testutils.NewMockGCSClient()
m.On("SetFileContents", mock.AnythingOfType("string"), 
     mock.AnythingOfType("[]byte")).Return(nil)
m.SetFileContents("foo", []byte("bar"))  

This fails with:

SetFileContents(string,[]uint8)
		0: "foo"
		1: []byte{...}

The closest call I have is: 

SetFileContents(mock.AnythingOfTypeArgument,mock.AnythingOfTypeArgument)
		0: "string"
		1: "[]byte"

This was pretty confusing, until I saw that the Mock Function seems to want []uint8 (And fmt.Sprintf("%T",[]byte{}) yields []uint8

This is worked around with

m.On("SetFileContents", mock.AnythingOfType("string"), 
     mock.AnythingOfType("[]uint8")).Return(nil)

but should really work as written, using "[]byte"

kjlubick avatar Jan 11 '17 15:01 kjlubick

Same here. trying to mock a []byte object only works with this work around.

xild avatar Feb 06 '17 17:02 xild

is there any update for that issue?

charlessachet avatar Jun 18 '19 20:06 charlessachet

I am having the same issue :(

vespian avatar Jun 28 '19 09:06 vespian

Same here

lootek avatar Oct 28 '19 12:10 lootek

Is this issue somehow solved? It still occurs on my side too

bjoernHeneka avatar May 15 '20 11:05 bjoernHeneka

We haven't had a chance (the time) to get around to it :) If anyone wants to take a stab at it, I'd be happy to review and provide feedback :)

boyan-soubachov avatar May 18 '20 09:05 boyan-soubachov

Hi. Is there any update on this one?

georgysavva avatar Nov 16 '20 10:11 georgysavva

It would be awesome if we could pass a regex in mock.AnythingOfType. For cases like following:

SomeMethod(*context.emptyCtx,*api.APIRequest)
		0: (*context.emptyCtx)(0xc000126008)
		1: &api.APIRequest{NewRequests:[]api.NewRequest{}, Language:"en"}

The closest call I have is: 

SomeMethod(mock.AnythingOfTypeArgument,mock.AnythingOfTypeArgument)
		0: "context"
		1: "api.APIRequest"

akij17 avatar Dec 01 '20 11:12 akij17

One strategy I've found that is more consistent than a regex is using https://pkg.go.dev/github.com/stretchr/[email protected]/mock#MatchedBy

For example, to match a context.Context (even if it's an empty context, or a value context), I have

var AnyContext = mock.MatchedBy(func(c context.Context) bool {
	// if the passed in parameter does not implement the context.Context interface, the
	// wrapping MatchedBy will panic - so we can simply return true, since we
	// know it's a context.Context if execution flow makes it here.
	return true
})

And I use it with myMock.On("Run", AnyContext).Return(7)

I bet this same trick would work for other cases where it is tempting to use a regex. From a code health standpoint, I wouldn't want to add regexes or more complexity to unit tests than is absolutely necessary; my unit tests don't have unit tests, so what if I have a bug in the regex?

kjlubick avatar Dec 01 '20 12:12 kjlubick

Any update here? It's still an issue.

gandarez avatar Jan 20 '23 14:01 gandarez

I get a lot of paper-cuts from this function as well. I feel that it would have been better if you had to provide a zero-value of the type, eg:

mock.AnythingOfType([]byte{})
mock.AnythingOfType((*int)(nil))

Or as this is is a breaking change anyway, how about a generic function in testify 2.0:

mock.AnythingOfType[[]byte]()
mock.AnythingOfType[*int]()

brackendawson avatar Jan 20 '23 15:01 brackendawson