mirror of https://github.com/stretchr/testify.git
commit
6905a3e663
50
mock/mock.go
50
mock/mock.go
|
@ -458,6 +458,47 @@ func AnythingOfType(t string) AnythingOfTypeArgument {
|
||||||
return AnythingOfTypeArgument(t)
|
return AnythingOfTypeArgument(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f argumentMatcher) Matches(argument interface{}) bool {
|
||||||
|
expectType := f.fn.Type().In(0)
|
||||||
|
|
||||||
|
if reflect.TypeOf(argument).AssignableTo(expectType) {
|
||||||
|
result := f.fn.Call([]reflect.Value{reflect.ValueOf(argument)})
|
||||||
|
return result[0].Bool()
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f argumentMatcher) String() string {
|
||||||
|
return fmt.Sprintf("func(%s) bool", f.fn.Type().In(0).Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builds an argumentMatcher from |fn|, which must be a function accepting a
|
||||||
|
// single argument (of any type) which returns a bool. If |fn| doesn't match
|
||||||
|
// the required signature, MathedBy() panics.
|
||||||
|
func MatchedBy(fn interface{}) argumentMatcher {
|
||||||
|
fnType := reflect.TypeOf(fn)
|
||||||
|
|
||||||
|
if fnType.Kind() != reflect.Func {
|
||||||
|
panic(fmt.Sprintf("assert: arguments: %s is not a func", fn))
|
||||||
|
}
|
||||||
|
if fnType.NumIn() != 1 {
|
||||||
|
panic(fmt.Sprintf("assert: arguments: %s does not take exactly one argument", fn))
|
||||||
|
}
|
||||||
|
if fnType.NumOut() != 1 || fnType.Out(0).Kind() != reflect.Bool {
|
||||||
|
panic(fmt.Sprintf("assert: arguments: %s does not return a bool", fn))
|
||||||
|
}
|
||||||
|
|
||||||
|
return argumentMatcher{fn: reflect.ValueOf(fn)}
|
||||||
|
}
|
||||||
|
|
||||||
// Get Returns the argument at the specified index.
|
// Get Returns the argument at the specified index.
|
||||||
func (args Arguments) Get(index int) interface{} {
|
func (args Arguments) Get(index int) interface{} {
|
||||||
if index+1 > len(args) {
|
if index+1 > len(args) {
|
||||||
|
@ -505,7 +546,14 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
|
||||||
expected = args[i]
|
expected = args[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() {
|
if matcher, ok := expected.(argumentMatcher); ok {
|
||||||
|
if matcher.Matches(actual) {
|
||||||
|
output = fmt.Sprintf("%s\t%d: \u2705 %s matched by %s\n", output, i, actual, matcher)
|
||||||
|
} else {
|
||||||
|
differences++
|
||||||
|
output = fmt.Sprintf("%s\t%d: \u2705 %s not matched by %s\n", output, i, actual, matcher)
|
||||||
|
}
|
||||||
|
} else if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() {
|
||||||
|
|
||||||
// type checking
|
// type checking
|
||||||
if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) {
|
if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) {
|
||||||
|
|
|
@ -147,6 +147,63 @@ func Test_Mock_On_WithFuncArg(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Mock_On_WithIntArgMatcher(t *testing.T) {
|
||||||
|
var mockedService TestExampleImplementation
|
||||||
|
|
||||||
|
mockedService.On("TheExampleMethod",
|
||||||
|
MatchedBy(func(a int) bool {
|
||||||
|
return a == 1
|
||||||
|
}), MatchedBy(func(b int) bool {
|
||||||
|
return b == 2
|
||||||
|
}), MatchedBy(func(c int) bool {
|
||||||
|
return c == 3
|
||||||
|
})).Return(0, nil)
|
||||||
|
|
||||||
|
assert.Panics(t, func() {
|
||||||
|
mockedService.TheExampleMethod(1, 2, 4)
|
||||||
|
})
|
||||||
|
assert.Panics(t, func() {
|
||||||
|
mockedService.TheExampleMethod(2, 2, 3)
|
||||||
|
})
|
||||||
|
assert.NotPanics(t, func() {
|
||||||
|
mockedService.TheExampleMethod(1, 2, 3)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Mock_On_WithPtrArgMatcher(t *testing.T) {
|
||||||
|
var mockedService TestExampleImplementation
|
||||||
|
|
||||||
|
mockedService.On("TheExampleMethod3",
|
||||||
|
MatchedBy(func(a *ExampleType) bool { return a.ran == true }),
|
||||||
|
).Return(nil)
|
||||||
|
|
||||||
|
mockedService.On("TheExampleMethod3",
|
||||||
|
MatchedBy(func(a *ExampleType) bool { return a.ran == false }),
|
||||||
|
).Return(errors.New("error!"))
|
||||||
|
|
||||||
|
assert.Equal(t, mockedService.TheExampleMethod3(&ExampleType{true}), nil)
|
||||||
|
assert.EqualError(t, mockedService.TheExampleMethod3(&ExampleType{false}), "error!")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Mock_On_WithFuncArgMatcher(t *testing.T) {
|
||||||
|
var mockedService TestExampleImplementation
|
||||||
|
|
||||||
|
fixture1, fixture2 := errors.New("fixture1"), errors.New("fixture2")
|
||||||
|
|
||||||
|
mockedService.On("TheExampleMethodFunc",
|
||||||
|
MatchedBy(func(a func(string) error) bool { return a("string") == fixture1 }),
|
||||||
|
).Return(errors.New("fixture1"))
|
||||||
|
|
||||||
|
mockedService.On("TheExampleMethodFunc",
|
||||||
|
MatchedBy(func(a func(string) error) bool { return a("string") == fixture2 }),
|
||||||
|
).Return(errors.New("fixture2"))
|
||||||
|
|
||||||
|
assert.EqualError(t, mockedService.TheExampleMethodFunc(
|
||||||
|
func(string) error { return fixture1 }), "fixture1")
|
||||||
|
assert.EqualError(t, mockedService.TheExampleMethodFunc(
|
||||||
|
func(string) error { return fixture2 }), "fixture2")
|
||||||
|
}
|
||||||
|
|
||||||
func Test_Mock_On_WithVariadicFunc(t *testing.T) {
|
func Test_Mock_On_WithVariadicFunc(t *testing.T) {
|
||||||
|
|
||||||
// make a test impl object
|
// make a test impl object
|
||||||
|
@ -937,6 +994,28 @@ func Test_Arguments_Diff_WithAnythingOfTypeArgument_Failing(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Arguments_Diff_WithArgMatcher(t *testing.T) {
|
||||||
|
matchFn := func(a int) bool {
|
||||||
|
return a == 123
|
||||||
|
}
|
||||||
|
var args Arguments = []interface{}{"string", MatchedBy(matchFn), true}
|
||||||
|
|
||||||
|
diff, count := args.Diff([]interface{}{"string", 124, true})
|
||||||
|
assert.Equal(t, 1, count)
|
||||||
|
assert.Contains(t, diff, `%!s(int=124) not matched by func(int) bool`)
|
||||||
|
|
||||||
|
diff, count = args.Diff([]interface{}{"string", false, true})
|
||||||
|
assert.Equal(t, 1, count)
|
||||||
|
assert.Contains(t, diff, `%!s(bool=false) not matched by func(int) bool`)
|
||||||
|
|
||||||
|
diff, count = args.Diff([]interface{}{"string", 123, false})
|
||||||
|
assert.Contains(t, diff, `%!s(int=123) matched by func(int) bool`)
|
||||||
|
|
||||||
|
diff, count = args.Diff([]interface{}{"string", 123, true})
|
||||||
|
assert.Equal(t, 0, count)
|
||||||
|
assert.Contains(t, diff, `No differences.`)
|
||||||
|
}
|
||||||
|
|
||||||
func Test_Arguments_Assert(t *testing.T) {
|
func Test_Arguments_Assert(t *testing.T) {
|
||||||
|
|
||||||
var args Arguments = []interface{}{"string", 123, true}
|
var args Arguments = []interface{}{"string", 123, true}
|
||||||
|
|
Loading…
Reference in New Issue