Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit 52b8cf0

Browse files
committed
Implement OverridableController to allow for mock overrides
1 parent 5b45562 commit 52b8cf0

File tree

5 files changed

+109
-1
lines changed

5 files changed

+109
-1
lines changed

gomock/callset.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ type callSet struct {
2727
expected map[callSetKey][]*Call
2828
// Calls that have been exhausted.
2929
exhausted map[callSetKey][]*Call
30+
// when set to true,
31+
allowOverride bool
3032
}
3133

3234
// callSetKey is the key in the maps in callSet
@@ -36,7 +38,18 @@ type callSetKey struct {
3638
}
3739

3840
func newCallSet() *callSet {
39-
return &callSet{make(map[callSetKey][]*Call), make(map[callSetKey][]*Call)}
41+
return &callSet{
42+
expected: make(map[callSetKey][]*Call),
43+
exhausted: make(map[callSetKey][]*Call),
44+
}
45+
}
46+
47+
func newOverridableCallSet() *callSet {
48+
return &callSet{
49+
expected: make(map[callSetKey][]*Call),
50+
exhausted: make(map[callSetKey][]*Call),
51+
allowOverride: true,
52+
}
4053
}
4154

4255
// Add adds a new expected call.
@@ -46,6 +59,11 @@ func (cs callSet) Add(call *Call) {
4659
if call.exhausted() {
4760
m = cs.exhausted
4861
}
62+
if cs.allowOverride {
63+
delete(m, key)
64+
m[key] = make([]*Call, 0)
65+
}
66+
4967
m[key] = append(m[key], call)
5068
}
5169

gomock/callset_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,24 @@ func TestCallSetAdd(t *testing.T) {
4242
}
4343
}
4444

45+
func TestCallSetAdd_WhenOverridable_ClearsPreviousExpectedAndExhausted(t *testing.T) {
46+
method := "TestMethod"
47+
var receiver interface{} = "TestReceiver"
48+
cs := newOverridableCallSet()
49+
50+
cs.Add(newCall(t, receiver, method, reflect.TypeOf(receiverType{}.Func)))
51+
numExpectedCalls := len(cs.expected[callSetKey{receiver, method}])
52+
if numExpectedCalls != 1 {
53+
t.Fatalf("Expected 1 expected call in callset, got %d", numExpectedCalls)
54+
}
55+
56+
cs.Add(newCall(t, receiver, method, reflect.TypeOf(receiverType{}.Func)))
57+
newNumExpectedCalls := len(cs.expected[callSetKey{receiver, method}])
58+
if newNumExpectedCalls != 1 {
59+
t.Fatalf("Expected 1 expected call in callset, got %d", newNumExpectedCalls)
60+
}
61+
}
62+
4563
func TestCallSetRemove(t *testing.T) {
4664
method := "TestMethod"
4765
var receiver interface{} = "TestReceiver"

gomock/controller.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,26 @@ func NewController(t TestReporter) *Controller {
105105
return ctrl
106106
}
107107

108+
// NewOverridableController returns a new Controller that allows for overridable call expectations
109+
func NewOverridableController(t TestReporter) *Controller {
110+
h, ok := t.(TestHelper)
111+
if !ok {
112+
h = &nopTestHelper{t}
113+
}
114+
ctrl := &Controller{
115+
T: h,
116+
expectedCalls: newOverridableCallSet(),
117+
}
118+
if c, ok := isCleanuper(ctrl.T); ok {
119+
c.Cleanup(func() {
120+
ctrl.T.Helper()
121+
ctrl.finish(true, nil)
122+
})
123+
}
124+
125+
return ctrl
126+
}
127+
108128
type cancelReporter struct {
109129
t TestHelper
110130
cancel func()

gomock/example_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,21 @@ func ExampleCall_DoAndReturn_captureArguments() {
4848
fmt.Printf("%s %s", r, s)
4949
// Output: I'm sleepy foo
5050
}
51+
52+
func ExampleCall_OverridableController_HappyPath() {
53+
t := &testing.T{} // provided by test
54+
ctrl := gomock.NewOverridableController(t)
55+
mockIndex := NewMockFoo(ctrl)
56+
var s string
57+
58+
mockIndex.EXPECT().Bar(gomock.AssignableToTypeOf(s)).DoAndReturn(
59+
func(arg string) interface{} {
60+
s = arg
61+
return "I'm sleepy"
62+
},
63+
)
64+
65+
r := mockIndex.Bar("foo")
66+
fmt.Printf("%s %s", r, s)
67+
// Output: I'm sleepy foo
68+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package gomock_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/golang/mock/gomock"
7+
)
8+
9+
func TestEcho_NoOverride(t *testing.T) {
10+
ctrl := gomock.NewOverridableController(t)
11+
mockIndex := NewMockFoo(ctrl)
12+
13+
mockIndex.EXPECT().Bar(gomock.Any()).Return("foo")
14+
res := mockIndex.Bar("input")
15+
16+
if res != "foo" {
17+
t.Fatalf("expected response to equal 'foo', got %s", res)
18+
}
19+
}
20+
21+
func TestEcho_WithOverride_BaseCase(t *testing.T) {
22+
ctrl := gomock.NewOverridableController(t)
23+
mockIndex := NewMockFoo(ctrl)
24+
25+
// initial expectation set
26+
mockIndex.EXPECT().Bar(gomock.Any()).Return("foo")
27+
// override
28+
mockIndex.EXPECT().Bar(gomock.Any()).Return("bar")
29+
res := mockIndex.Bar("input")
30+
31+
if res != "bar" {
32+
t.Fatalf("expected response to equal 'bar', got %s", res)
33+
}
34+
}

0 commit comments

Comments
 (0)