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

Feature: support user implementations of Match when diffing mock arguments #1695

Open
connorszczepaniak-wk opened this issue Jan 15, 2025 · 1 comment

Comments

@connorszczepaniak-wk
Copy link

Description

I've found it to be common that I want to set up a mock expectation for a call that takes in a struct type, and I want the matcher to match only some of the struct fields. Usually it's because there's a field with something like metrics or a timestamp that I don't consider to be relevant to my test and it's fine if those don't match, but the rest should.

The existing solution to this is to write a mock.MatchedBy and write a function that only checks the fields I care about. This works well enough, but there are types where we want to define globally that only certain fields should be matched when a value of that type is passed into a mock.On.

Proposed solution

A solution to this would be to use an interface within Arguments.Diff -- currently it type-asserts on argumentMatcher which handles the mock.MatchedBy case, but if there instead was an interface with a Matches function that that type assertion uses, it would allow users to implement Matches on their own types to define custom matching behavior.

The relevant branch is here:
https://github.com/stretchr/testify/blob/master/mock/mock.go#L976-L991

The interface could look like this:

type Matcher interface {
	Matches(argument interface{}) bool
}

And then the type assertion would simply change to the following:

if matcher, ok := expected.(Matcher); ok {

This would be backwards compatible with mock.MatchedBy because it already implements the new interface.

Use case

See above, but briefly: I want to define custom matching behavior for a given type that the mock package uses if a type implements the interface.

@connorszczepaniak-wk
Copy link
Author

Another thought: maybe if we went down this path, we should use a name other than Matches for the interface function because that seems likely to collide with other methods that may prefer to be called Matches. Maybe we could do something like this:

type ArgumentMatcher interface {
	MockArgumentMatches(argument interface{}) bool
}

And then we'd just implement MockArgumentMatches on the current mock.MatchedBy implementation.

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

1 participant