-
Notifications
You must be signed in to change notification settings - Fork 423
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
Variadic Method Improvements (Work In Progress - Do Not Merge) #550
Conversation
@@ -40,3 +40,5 @@ require ( | |||
gopkg.in/ini.v1 v1.66.6 // indirect | |||
gopkg.in/yaml.v3 v3.0.1 // indirect | |||
) | |||
|
|||
replace github.com/stretchr/testify => github.com/dlwyatt/testify v1.9.9 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
temporary until we see if testify takes the linked PR.
Codecov ReportBase: 72.59% // Head: 73.72% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #550 +/- ##
==========================================
+ Coverage 72.59% 73.72% +1.13%
==========================================
Files 6 6
Lines 1277 1332 +55
==========================================
+ Hits 927 982 +55
Misses 306 306
Partials 44 44
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
I'll take a look over this and give you my thoughts in a bit |
You already touch on this but I want to get some clarity on this specific question. Take this production code: func Foo(s ...any) {}
// case 1
Foo("foo", "bar")
// case 2
Foo("foo") In the tests I may have this: mockIntf.On("Foo", mock.Anything) I may either:
It's not clear to me in the proposal how one would differentiate between those two cases. In my opinion, it seems like it was a mistake allowing the syntactic sugar because now these cases I mentioned are ambiguous. With
|
"now these cases I mentioned are ambiguous" That's an interesting point. I can see a few possibilities here for matching exactly one argument, assuming the testify PR gets merged:
|
This feels inconsistent and will be a weird edge case.
This is the best option IMO. But then like you mentioned before, you get into a situation where someone might be passing in a slice to the mock implementation as the first argument to the variadic. Kind of weird but... it could happen! If the code has to disambiguate “is this meant to be a single argument or is it the vararg value itself” then it becomes an intractable problem.
It's an interesting thought. I would rather not start maintaining our own sentinels as it's this weird edge case wart. In my opinion it really seems like the way that solves all of these problems is getting your testify PR merged and making |
Oh, one other option. Make a custom type alias for []any for when you want to be explicit about the slice. If you pass in a single arg of that type, mockery knows to pass it unmodified to testify. Otherwise, roll it up. That covers all the bases (for these examples I'm using VarSlice as the made up type name):
This does still introduce some new usage and could break existing tests, but handles it all in non ambiguous ways without losing the variadic style syntax for most use cases. |
Come to think of it, this could be done in a different way that doesn't require a change to testify. Leave the old unroll behavior mostly as is, and just add a new placeholder to mockery for the "match any number of arguments" case. Old tests continue to work fine. Benefit of --unroll-variadic=false is available with the nicer syntax. |
I am inclined to not fix this and make I think there are merits to the argument either way but my personal preference is to not "fix" this in mockery, and just deprecate |
@dlwyatt I'm reaching out to the testify maintainers directly to see if we can get your PR merged. |
Description
Proposed improvements for mocking variadic methods. Moving the dialogue from #541 over here so further discussion can be made alongside visible code diffs.
Note - In order to cut down on or eliminate the number of breaking changes this code would introduce, I have a PR open in testify here: stretchr/testify#1348 . I don't know if they will take that PR yet. For now, this PR points at my fork of testify to demonstrate how most of the old tests are working with the new generated code.
Lots more details in the linked issue, but the short version here is that this PR aims to get rid of the --unroll-variadic flag, and have mockery give us the best of both worlds from how it works today when that flag is set to either true or false. Namely, that you can use mock's
On
,AssertCalled
, andAssertNotCalled
functions without manually building slice values for the variadic parameters, and you can still use a singlemock.Anything
value against variadic parameters to match any number of arguments.Assuming testify takes the PR, there is still one breaking change remaining in the existing code; you can't manually build up a slice value for the variadic parameter anymore, which was a syntax still being tested by certain parts of generator_test.go (around line 1500-1600). It may be possible to still allow that syntax in most cases by having the generated mocks look for situations where a single expected argument was passed for a variadic parameter, and that argument is itself a slice. In that case, pass the slice on unmodified to testify. (This might still cause the odd corner case to fail, when someone really does want a slice containing exactly one other slice for some reason. Hopefully there's not too much Go code in the world that looks that way. 😄 )
Type of change
Version of Golang used when building/testing:
How Has This Been Tested?
Run
make test
Checklist