-
Notifications
You must be signed in to change notification settings - Fork 9
/
doc.go
110 lines (78 loc) · 3.36 KB
/
doc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright 2013 Julian Phillips. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
withmock is a tool to assist in mocking code for testing.
The basic idea is that you can mark import statements to indicate packages that
should be mocked. Then, if you run your test via withmock then mock versions of
the marked packages will be generated - and the tests will be run using those
packages instead of the real ones.
Creating Mocks
To mark an import for mocking, simply append a comment consisting of just the
word mock to the end of the import line in the xxx_test.go file.
So if we had the import statement:
import (
"fmt"
"os"
"os/exec"
"example.com/some/external/package"
)
then we could mark the external package for mocking by changing it to:
import (
"fmt"
"os"
"os/exec"
"example.com/some/external/package" // mock
)
The mocking is not restricted to external packages. Though often we want to
keep access to the original package for use in the test code itself. So,
keeping the same example, we might want to use a mock version of fmt in the code
under test. So, now we change the import to:
import (
"fmt"
"os"
"os/exec"
mockfmt "fmt" // mock
"example.com/some/external/package" // mock
)
So, when run, the non-test code will be using the mocked fmt and external
packages, and the test code will have the proper fmt, the mocked fmt as mockfmt,
and the mocked external package using it's own name (which will assume it ext,
for the purposes of this documentation).
Using Mocks
The generated mock code behaves much like the code generated by gomock's mockgen
, particularly when dealing with methods on types. Though there are some
differences, due to the whole package nature.
The first thing to do with a mocked package is to set the controller. This
needs to be done before any mocked method or function is called or expectation
is set - otherwise the generated code will cause a panic. To set the
controller, we use the special mock object returned by the MOCK() function, and
call it's SetController method:
// Create a gomock controller, and arrange for it's finish to be called
ctrl := gomock.NewController(t)
defer ctrl.Finish()
// Setup the mockfmt mock package
mockfmt.MOCK().SetController(ctrl)
// Setup the ext mock package
ext.MOCK().SetController(ctrl)
Once you have set the controller then you can set your mock expectations, either
using the EXPECT() function for function expectations, or the EXPECT() method
for any method expectations. For example, if there was a type called
UsefulType, and we were expecting it's HandyMethod to be called - followed by a
message printed indicating the result, we might set our expectations as follows:
// Create a UsefulType instance
ut := &ext.UsefulType{}
// We expect to see HandyMethod called, and we want to return true
ut.EXPECT().HandyMethod().Return(true)
// And we expect to see our returned value printed
mockfmt.EXPECT().Printf("HandyMethod returned: %v\n", true)
And then finally we can call our code under test, passing it our mocked
UsefulType instance:
// And now, call the code under test
importantFunction(ut)
Running the tests
And now we just need to wrap our call to "go test", so we run:
withmock go test
and gomock and the Go testing framework will do the rest for us ... :D
*/
package main