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

Implement Testify custom matchers via mock.MatchedBy #6

Open
StevenACoffman opened this issue Dec 22, 2020 · 2 comments
Open

Implement Testify custom matchers via mock.MatchedBy #6

StevenACoffman opened this issue Dec 22, 2020 · 2 comments

Comments

@StevenACoffman
Copy link

StevenACoffman commented Dec 22, 2020

Hi, I saw the recent gomock discussion and would love documentation on how to Implement Testify's custom matchers via mock.MatchedBy using this library.

// Anything and AnythingOfType matchers
mockDoer.
    On("Do", mock.Anything, mock.AnythingOfType("string"))

// Custom matcher
mockDoer.
    On("Do", 1, mock.MatchedBy(func(x string) bool {
        return strings.HasPrefix(x, "abc")
    })
@corbym
Copy link
Owner

corbym commented Dec 23, 2020

Although I haven't used the testify library, I do not think we could use gocrest matchers out of the box for the mock.MatchedBy method - the testify code would probably need an interface ala gomock that matches the func Matches(x interface{}) bool matcher method of the gocrest struct.

e.g.

package mock

type Matcher interface {
  // Matches returns whether x is a match.
  Matches(x interface{}) bool
}

The mock.MatchedBy would then need to use the interface instead of the empty interface:

func MatchedBy(fn interface{}) argumentMatcher

would become

func MatchedBy(fn mock.Matcher) argumentMatcher

With that you can then write:

mockDoer.
    On("Do", 1, mock.MatchedBy(has.Prefix("abc"))

... but until mock.MatchedBy changes it's interface, this isn't something we could support alone.

The other option is to make the argumentMatcher an interface instead of a struct:

// argumentMatcher performs custom argument matching, returning whether or
// not the argument is matched by the expectation fixture function.
type argumentMatcher struct {
	// fn is a function which accepts one argument, and returns a bool.
	fn reflect.Value
}

so you could write something like:

mockDoer.
    On("Do", 1, has.Prefix("abc"))

-- not sure that would work though as I haven't tested it.

@jcyamacho
Copy link

At least would be nice to have the public Matcher interface from @corbym example instead of argumentMatcher type. This way we can create custom matchers to reuse.

if MatchedBy becomes like:

func MatchedBy(fn interface{}) Matcher

and internally in the Argumnts.Diff function this code:

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

becomes more like:

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

then we can create custom matchers implementing the Matcher interface

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

No branches or pull requests

3 participants