Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mock returns panic when API uses context #519

Open
santoshaitha opened this issue Nov 14, 2017 · 15 comments
Open

mock returns panic when API uses context #519

santoshaitha opened this issue Nov 14, 2017 · 15 comments

Comments

@santoshaitha
Copy link

santoshaitha commented Nov 14, 2017

go test command returns below panic when we try to use mocks.On: Does testify/mock support context as a parameter.

it reports it is getting type as context.emptyContext

mockery generated API as below:

// SetSchema provides a mock function with given fields: ctx, in
func (_m *MockUtils) SetSchema(ctx context.Context, in *models.Schema) (*models.Schema, error) {
ret := _m.Called(ctx, in)

var r0 *models.Schema
if rf, ok := ret.Get(0).(func(context.Context, *models.Schema) *models.Schema); ok {
	r0 = rf(ctx, in)
} else {
	if ret.Get(0) != nil {
		r0 = ret.Get(0).(*models.Schema)
	}
}

var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *models.Schema) error); ok {
	r1 = rf(ctx, in)
} else {
	r1 = ret.Error(1)
}

return r0, r1

}

I am using mocks.On as below:

func TestUtils(){
//
.....
///
mclient.On("SetSchema", mock.AnythingOfType("context.Context"), mock.AnythingOfType("*models.Schema")).Return(schemaData)
ctx := context.Background()
s, _ := mockutils.SetSchema(ctx, schemaData)
}

i see below panic from mock package.
mock: Unexpected Method Call

SetSchema(*context.emptyCtx,*models.Schema)
*0: (context.emptyCtx)(0xc420011058)
1: &models.Schema{ID:"", SchemaID:""}

The closest call I have is:

SetSchema(mock.AnythingOfTypeArgument,mock.AnythingOfTypeArgument)
0: "context.Context"
1: "*models.Schema"

goroutine 11 [running]:
testing.tRunner.func1(0xc4200740d0)
/usr/local/go/src/testing/testing.go:622 +0x29d
panic(0x14ba5a0, 0xc4204c32b0)
/usr/local/go/src/runtime/panic.go:489 +0x2cf
vendor/github.com/stretchr/testify/mock.(*Mock).MethodCalled(0xc4202e24c0, 0x17ff0d6, 0x9, 0xc4204c5080, 0x2, 0x2, 0x7, 0x2, 0xc42003c960)
/Users/saaitha/Documents/vendor/github.com/stretchr/testify/mock/mock.go:311 +0x6db
vendor/github.com/stretchr/testify/mock.(*Mock).Called(0xc4202e24c0, 0xc4204c5080, 0x2, 0x2, 0x1, 0xc42003c9d8, 0x11eae6a)

@jamesonjlee
Copy link

jamesonjlee commented Dec 1, 2017

have you tried *context.emptyCtx or context.emptyCtx or AnythingOfType(context.Background())?

I had a similar issue that was solved by passing in name of the context type that I expect to be passed.

example of context.Background() != context.Context when reflected.
https://play.golang.org/p/w9vIzEUZAg

@santoshaitha
Copy link
Author

Yes i tried all these types got similar kind of error each time

@santoshaitha
Copy link
Author

It works with AnythingOfType(*context.emptyCtx). But as context.Context is of type interface, isn't AnythingOfType should accept context.Context also?

@ernesto-jimenez
Copy link
Member

@santoshaitha yes, it should allow for interfaces.

We would need to change the reflection checks inside AnythingOfType to accept an interface and check whether the argument is assignable to that interface.

@santoshaitha
Copy link
Author

Thanks Hope it will be fixed in future commits.

@evan2645
Copy link

@santoshaitha this is under go 1.9.2? Can you reproduce under go 1.8.3?

@evan2645
Copy link

evan2645 commented Jan 23, 2018

I have bumped into something like this after upgrading to go 1.9.2 and updating my project dependencies. I don't fully understand the nature of what's described here, but my failure mode seems similar.

I'm running into panics when trying to return interfaces from EXPECT calls, i.e. EXPECT().Foo().Return(interface_conforming_type_here). Using testify's current master (87b1dfb), I've isolated the introduction of the panic to this change in gomock: golang/mock@0ee1ab2

This very well may be a different problem than the one described here... if so just let me know, I'm happy to post it elsewhere. For now, I'll be pinning gomock version to the commit just prior.

EDIT>> I am using testify/suite. I didn't see any issues or PRs open against gomock and this change has been around for some time, so it's possible it has nothing to do with testify at all... hopefully someone more knowledgable than myself can chime in here :)

@santoshaitha
Copy link
Author

Yes it is different problem than described in this defect. The issue in this defect is with AnythingOfType doesn't accept interface type but where as your issue related to Return() API.

@ghost
Copy link

ghost commented Nov 10, 2020

Have you solved your issue? I believe that I've encountered this and that you can work around it by using
mock.MatchedBy(func(ctx context.Context) bool { return true}) instead. This isn't the prettiest thing but it is easy to create a variable once and reuse it.

@georgysavva
Copy link

Hi. Is there any update on adding the ability to write mock.AnythingOfType("context.Context")?

@rana
Copy link

rana commented Nov 23, 2020

mock.MatchedBy(func(ctx context.Context) bool { return true})

This solved it for the time being

@nishanths
Copy link

nishanths commented Apr 2, 2021

Is it possible to use MatchedBy if my method takes multiple arguments? e.g.

func (o *Obj) Create(ctx context.Context, id string) error

The documentation requires the argument function passed to MatchedBy to have exactly one parameter. Otherwise, as documented, it panics.

@nishanths
Copy link

I was able to resolve my earlier question using AnythingOfType.

go version go1.16 darwin/amd64
github.com/stretchr/testify v1.7.0
obj.
	On("Create", mock.AnythingOfType(fmt.Sprintf("%T", context.Background())), "xyz").
	Return(nil).
	Times(1)

This also seems like a possible solution to @georgysavva's question above.

Hi. Is there any update on adding the ability to write mock.AnythingOfType("context.Context")?

@nishanths
Copy link

Is it possible to use MatchedBy if my method takes multiple arguments?

On further working this package, I think I would have had to do:

On("Create", 
    mock.MatchedBy(func(_ context.Context) bool { return true }), 
    mock.MatchedBy(func(s string) bool { ... }), 
)

in order to suit:

func (o *Obj) Create(ctx context.Context, id string) error

@yuseferi
Copy link

mock.Anything
or
mock.MatchedBy(func(ctx context.Context) bool { return true}}
works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants