├── LICENSE ├── README.md ├── doer └── doer.go ├── match └── oftype.go ├── mocks └── mock_doer.go └── user ├── user.go └── user_test.go /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Sergey Grebenshchikov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # testing-with-gomock 2 | 3 | Supporting materials for the blog post [Testing with GoMock](https://blog.codecentric.de/2017/08/gomock-tutorial/). 4 | -------------------------------------------------------------------------------- /doer/doer.go: -------------------------------------------------------------------------------- 1 | package doer 2 | 3 | //go:generate mockgen -destination=../mocks/mock_doer.go -package=mocks github.com/sgreben/testing-with-gomock/doer Doer 4 | 5 | type Doer interface { 6 | DoSomething(int, string) error 7 | } 8 | -------------------------------------------------------------------------------- /match/oftype.go: -------------------------------------------------------------------------------- 1 | package match 2 | 3 | import ( 4 | "reflect" 5 | 6 | "github.com/golang/mock/gomock" 7 | ) 8 | 9 | type ofType struct{ t string } 10 | 11 | func OfType(t string) gomock.Matcher { 12 | return &ofType{t} 13 | } 14 | 15 | func (o *ofType) Matches(x interface{}) bool { 16 | return reflect.TypeOf(x).String() == o.t 17 | } 18 | 19 | func (o *ofType) String() string { 20 | return "is of type " + o.t 21 | } 22 | -------------------------------------------------------------------------------- /mocks/mock_doer.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: github.com/sgreben/testing-with-gomock/doer (interfaces: Doer) 3 | 4 | package mocks 5 | 6 | import ( 7 | gomock "github.com/golang/mock/gomock" 8 | ) 9 | 10 | // MockDoer is a mock of Doer interface 11 | type MockDoer struct { 12 | ctrl *gomock.Controller 13 | recorder *MockDoerMockRecorder 14 | } 15 | 16 | // MockDoerMockRecorder is the mock recorder for MockDoer 17 | type MockDoerMockRecorder struct { 18 | mock *MockDoer 19 | } 20 | 21 | // NewMockDoer creates a new mock instance 22 | func NewMockDoer(ctrl *gomock.Controller) *MockDoer { 23 | mock := &MockDoer{ctrl: ctrl} 24 | mock.recorder = &MockDoerMockRecorder{mock} 25 | return mock 26 | } 27 | 28 | // EXPECT returns an object that allows the caller to indicate expected use 29 | func (_m *MockDoer) EXPECT() *MockDoerMockRecorder { 30 | return _m.recorder 31 | } 32 | 33 | // DoSomething mocks base method 34 | func (_m *MockDoer) DoSomething(_param0 int, _param1 string) error { 35 | ret := _m.ctrl.Call(_m, "DoSomething", _param0, _param1) 36 | ret0, _ := ret[0].(error) 37 | return ret0 38 | } 39 | 40 | // DoSomething indicates an expected call of DoSomething 41 | func (_mr *MockDoerMockRecorder) DoSomething(arg0, arg1 interface{}) *gomock.Call { 42 | return _mr.mock.ctrl.RecordCall(_mr.mock, "DoSomething", arg0, arg1) 43 | } 44 | -------------------------------------------------------------------------------- /user/user.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import "github.com/sgreben/testing-with-gomock/doer" 4 | 5 | type User struct { 6 | Doer doer.Doer 7 | } 8 | 9 | func (u *User) Use() error { 10 | return u.Doer.DoSomething(123, "Hello GoMock") 11 | } 12 | -------------------------------------------------------------------------------- /user/user_test.go: -------------------------------------------------------------------------------- 1 | package user_test 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/golang/mock/gomock" 9 | "github.com/sgreben/testing-with-gomock/match" 10 | "github.com/sgreben/testing-with-gomock/mocks" 11 | "github.com/sgreben/testing-with-gomock/user" 12 | ) 13 | 14 | func TestUse(t *testing.T) { 15 | mockCtrl := gomock.NewController(t) 16 | defer mockCtrl.Finish() 17 | 18 | mockDoer := mocks.NewMockDoer(mockCtrl) 19 | testUser := &user.User{Doer: mockDoer} 20 | 21 | // Expect Do to be called once with 123 and "Hello GoMock" as parameters, and return nil from the mocked call. 22 | mockDoer.EXPECT().DoSomething(123, "Hello GoMock").Return(nil).Times(1) 23 | 24 | testUser.Use() 25 | } 26 | 27 | func TestUseReturnsErrorFromDo(t *testing.T) { 28 | mockCtrl := gomock.NewController(t) 29 | defer mockCtrl.Finish() 30 | 31 | dummyError := errors.New("dummy error") 32 | mockDoer := mocks.NewMockDoer(mockCtrl) 33 | testUser := &user.User{Doer: mockDoer} 34 | 35 | // Expect Do to be called once with 123 and "Hello GoMock" as parameters, and return dummyError from the mocked call. 36 | mockDoer.EXPECT().DoSomething(123, "Hello GoMock").Return(dummyError).Times(1) 37 | 38 | err := testUser.Use() 39 | 40 | if err != dummyError { 41 | t.Fail() 42 | } 43 | } 44 | 45 | func TestUseMatchersExample1(t *testing.T) { 46 | mockCtrl := gomock.NewController(t) 47 | defer mockCtrl.Finish() 48 | 49 | mockDoer := mocks.NewMockDoer(mockCtrl) 50 | testUser := &user.User{Doer: mockDoer} 51 | 52 | mockDoer.EXPECT().DoSomething(gomock.Any(), "Hello GoMock") 53 | 54 | testUser.Use() 55 | } 56 | 57 | func TestUseMatchersExample2(t *testing.T) { 58 | mockCtrl := gomock.NewController(t) 59 | defer mockCtrl.Finish() 60 | 61 | mockDoer := mocks.NewMockDoer(mockCtrl) 62 | testUser := &user.User{Doer: mockDoer} 63 | 64 | mockDoer.EXPECT(). 65 | DoSomething(123, match.OfType("string")). 66 | Return(nil). 67 | Times(1) 68 | 69 | testUser.Use() 70 | } 71 | 72 | func TestUseOrderExample1(t *testing.T) { 73 | mockCtrl := gomock.NewController(t) 74 | defer mockCtrl.Finish() 75 | 76 | mockDoer := mocks.NewMockDoer(mockCtrl) 77 | 78 | callFirst := mockDoer.EXPECT().DoSomething(1, "first this") 79 | mockDoer.EXPECT().DoSomething(2, "then this").After(callFirst) 80 | mockDoer.EXPECT().DoSomething(2, "or this").After(callFirst) 81 | 82 | mockDoer.DoSomething(1, "first this") 83 | mockDoer.DoSomething(2, "or this") 84 | mockDoer.DoSomething(2, "then this") 85 | } 86 | 87 | func TestUseOrderExample2(t *testing.T) { 88 | mockCtrl := gomock.NewController(t) 89 | defer mockCtrl.Finish() 90 | 91 | mockDoer := mocks.NewMockDoer(mockCtrl) 92 | 93 | gomock.InOrder( 94 | mockDoer.EXPECT().DoSomething(1, "first this"), 95 | mockDoer.EXPECT().DoSomething(2, "then this"), 96 | mockDoer.EXPECT().DoSomething(3, "then this"), 97 | mockDoer.EXPECT().DoSomething(4, "finally this"), 98 | ) 99 | 100 | mockDoer.DoSomething(1, "first this") 101 | mockDoer.DoSomething(2, "then this") 102 | mockDoer.DoSomething(3, "then this") 103 | mockDoer.DoSomething(4, "finally this") 104 | } 105 | 106 | func TestUseActionExamples(t *testing.T) { 107 | mockCtrl := gomock.NewController(t) 108 | defer mockCtrl.Finish() 109 | 110 | mockDoer := mocks.NewMockDoer(mockCtrl) 111 | 112 | mockDoer.EXPECT(). 113 | DoSomething(gomock.Any(), gomock.Any()). 114 | Return(nil). 115 | Do(func(x int, y string) { 116 | fmt.Println("Called with x =", x, "and y =", y) 117 | }) 118 | 119 | mockDoer.EXPECT(). 120 | DoSomething(gomock.Any(), gomock.Any()). 121 | Return(nil). 122 | Do(func(x int, y string) { 123 | if x > len(y) { 124 | t.Fail() 125 | } 126 | }) 127 | 128 | mockDoer.DoSomething(123, "test") 129 | mockDoer.DoSomething(2, "test") 130 | 131 | } 132 | --------------------------------------------------------------------------------