Matching library for use with golang/gomock
All matchers in this package implements the Matcher interface and can thusly be used with mocks from golang/gomock.
Example usage of Record matcher, but all matchers work in a similar way:
import "github.com/Storytel/gomock-matchers"
func TestSomething(t *testing.T) {
// Set up a new matcher
matcher := matchers.Record(gomock.Eq(12))
// Expect `MyFunc` to be called on `mock` with argument equal to 12
mock.EXPECT().MyFunc(matcher).Return(nil)
// Run the test this which will expect the EXPECT()
DUT()
// For the RecordMatcher, you can get the argument. Other matchers have other characteristics.
if 12 != matcher.Get().(int) {
t.Fail()
}
}
RegexpMatcher - Matcher which accepts a string to be interpreted as a Go Regexp.
Regexpmatcher returns a matcher which will match if the supplied string, interpreted as a regexp, matches the input string.
This is useful when you don't know exactly what the string might be in a run. Maybe it's a timestamp or something else outside of your control.
func TestRegexpMatcher(t *testing.T) {
m := matchers.Regexp("^[^@]+@.+$")
m.Matches("[email protected]") // true
m.Matches("daisy") // false
}
RecordMatcher - Proxy matcher which captures the argument for further inspection.
Wraps another matcher and records the value of the argument it's called with.This can be used if you need to do further investigations. For instance when the argument is a function, and you want to test that function.
type MyFunc func() int
func TestRecord(t *testing.T) {
assert := assert.New(t)
m := matchers.Record(gomock.Any())
m.Matches(MyFunc(func () int { return 12 }))
f, ok := m.Get().(MyFunc)
assert.True(ok)
assert.Equal(12, f())
}
SameMatcher - Matcher which checks if values are the same
This differs from gomock.Eq
in that it does a comparison check with ==
and not a
reflect.DeepEqual
. This means that two pointers are only same if they point to the
same memory address
func TestSame(t *testing.T) {
assert := assert.New(t)
myString := "something"
otherString := "something"
m := matchers.Same(&myString)
assert.True(m.Matches(&myString))
assert.False(m.Matches(&otherString)) // Not the same pointer
m2 := matchers.Same(myString)
assert.True(m2.Matches(myString))
assert.True(m2.Matches(otherString)) // Not pointers, values are the same
}
AsyncBlockMatcher - Matcher which provides channel signaling when `Matches` is called
AsyncBlock returns a matcher holding a channel which will be signaled when
the Matches
function is called. AsyncBlock will wrap any other matcher
to do the actual matching.
This is useful if the code you're testing is spawning a go function which will
invoke your mock at some time in the future. The channel gives you an easy way
to wait for that invokation (using <- matcher.Channel()
) and then do assertions.
func TestAsyncBlockMatcher(t *testing.T) {
assert := assert.New(t)
m := matchers.AsyncBlock(gomock.Eq("12"))
didMatch := false
go func() {
didMatch = m.Matches("12")
}()
// This blocks until `Matches` is actually called
<-m.Channel()
assert.True(didMatch)
}