uber-go / mock

GoMock is a mocking framework for the Go programming language.
Apache License 2.0
1.82k stars 104 forks source link

Order of calls is enforced when InOrder() or After() were not invoked #95

Open tehsphinx opened 9 months ago

tehsphinx commented 9 months ago

This bug is still around:


Actual behaviour When I have EXPECT set for two calls to the same method with different parameters - the order of EXPECT definitions enforces the order of the actual calls.

I.e. when having these expectations defined:

test.mock.EXPECT().DoSomething("foo").Return(&Response{})
test.mock.EXPECT().DoSomething("bar").Return(&Response{})

and code under test defined as

service.DoSomething("foo")
service.DoSomething("bar")

Just changing the order of definitions of calls expected with no other changes, i.e. making it

test.mock.EXPECT().DoSomething("bar").Return(&Response{}) test.mock.EXPECT().DoSomething("foo").Return(&Response{}) makes the test fail.

Expected behavior As per documentation:

By default, expected calls are not enforced to run in any particular order.

So no order should be enforced as long as the actual calls match any of the defined expectations.

tehsphinx commented 9 months ago

The issue seems to be linked to complex types. With base types it seems to be working (tested with int). But when the only difference is an int wrapped into 3 structs, it fails to be orderless.

jacob2964 commented 9 months ago

I'm experiencing this as well on v0.3.0.

martskins commented 9 months ago

I experienced this myself and narrowed it down to reflect.DeepEqual not being true for proto messages (which is expected). I wrote a custom matcher for the types I was using in my expected calls that only matches the known, comparable fields in those proto messages and that fixed it. Don't quite understand yet why it works if you set the calls in the right order, but it all pointed out to that being an issue in my case.

Not sure what a proper fix for this would look like if that's confirmed to be the problem, but happy to try and implement it if given some pointers.

pratheeshm commented 7 months ago

any update on this issue?

j0hnsmith commented 6 months ago

This is a problem when you have goroutines that may make calls in an unspecified order.

To force an order there's gomock.InOrder() but there's no inverse function to force no ordering.

tehsphinx commented 6 months ago

It is also an issue if calls to a method are dependent on a map iteration, since the map iteration is randomised. By default the order should not matter (as per documentation), but unfortunately that is not always true.