-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Export mock.argumentMatcher #333
Conversation
@connor4312 sorry for the late reply. It has been a crazy summer :) I would rather avoid exporting an struct that cannot be properly initialised. Instead, it would be better to define an The tricky part is that we must ensure the interface is never satisfied by a struct from some other package, otherwise we might have weird collisions and we would not be able to add anything to the interface without breaking backwards compatibility. The idea would be to export type ArgumentMatcher interface {
Matches(interface{}) bool
String()
// This method ensures only `mock` package can implement ArgmentMatchers
private()
} Then, we include: func (argumentMatcher) private() { }
With these changes, you could define functions like yours and the package would be much safer to use. What do you think? Do you want to make those changes? |
Hm, I see the issue, but to me it seems like that might be a bit of an abuse of the type system. Perhaps a struct or function type which encapsulates a predicate, rather than using an interface. // An ArgumentMatcher takes a function argument and returns whether it
// matches the Call's desired signature
type ArgumentMatcher func(v interface{}) bool To be a bit more ambitious, have Additionally, some existing code like |
My point is that I would rather lock-in this feature so only Adding a private method to an exported interface is not an abuse of the type system, it is a safeguard to be able to export an interface only your package can satisfy so you are free to modify it without breaking backwards compatibility. Thinking more about this, I would probably do: type ArgumentMatcher interface {
ArgumentMatches(interface{}) error
// This method ensures only `mock` package can implement ArgmentMatchers
private()
} And refactor the current With that change, not only we can definitely |
The For now, the right way to rewrite the use case of the description of this issue is to use the type Counter struct{ x int }
func counterArg(expectedX int) any {
return mock.MatchedBy(func(c *Counter) bool {
return c.x == expectedX
})
}
mock.On("Method", counterArg(1))
mock.On("Method", counterArg(2))
mock.On("Method", counterArg(3)) |
This allows the creation of predicate-generating functions, which can make code a lot cleaner. To give a very simple example, this is not possible with the current non-exported argumentMatcher:
Also fixes the outstanding lint issues from #230