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

Commit cab8569

Browse files
committed
Implement OverridableController to allow for mock overrides
1 parent fcef047 commit cab8569

File tree

5 files changed

+106
-0
lines changed

5 files changed

+106
-0
lines changed

gomock/callset.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ type callSet struct {
2929
expectedMu *sync.Mutex
3030
// Calls that have been exhausted.
3131
exhausted map[callSetKey][]*Call
32+
// when set to true,
33+
allowOverride bool
3234
}
3335

3436
// callSetKey is the key in the maps in callSet
@@ -45,6 +47,15 @@ func newCallSet() *callSet {
4547
}
4648
}
4749

50+
func newOverridableCallSet() *callSet {
51+
return &callSet{
52+
expected: make(map[callSetKey][]*Call),
53+
expectedMu: &sync.Mutex{},
54+
exhausted: make(map[callSetKey][]*Call),
55+
allowOverride: true,
56+
}
57+
}
58+
4859
// Add adds a new expected call.
4960
func (cs callSet) Add(call *Call) {
5061
key := callSetKey{call.receiver, call.method}
@@ -56,6 +67,11 @@ func (cs callSet) Add(call *Call) {
5667
if call.exhausted() {
5768
m = cs.exhausted
5869
}
70+
if cs.allowOverride {
71+
delete(m, key)
72+
m[key] = make([]*Call, 0)
73+
}
74+
5975
m[key] = append(m[key], call)
6076
}
6177

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
@@ -114,6 +114,26 @@ type ControllerOption interface {
114114
apply(*Controller)
115115
}
116116

117+
// NewOverridableController returns a new Controller that allows for overridable call expectations
118+
func NewOverridableController(t TestReporter) *Controller {
119+
h, ok := t.(TestHelper)
120+
if !ok {
121+
h = &nopTestHelper{t}
122+
}
123+
ctrl := &Controller{
124+
T: h,
125+
expectedCalls: newOverridableCallSet(),
126+
}
127+
if c, ok := isCleanuper(ctrl.T); ok {
128+
c.Cleanup(func() {
129+
ctrl.T.Helper()
130+
ctrl.finish(true, nil)
131+
})
132+
}
133+
134+
return ctrl
135+
}
136+
117137
type cancelReporter struct {
118138
t TestHelper
119139
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+
}

gomock/overridable_controller_test.go

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)