@@ -3,113 +3,146 @@ Mock library for Dart inspired by [Mockito](https://github.com/mockito/mockito).
3
3
[ ![ Pub] ( https://img.shields.io/pub/v/mockito.svg )] ( )
4
4
[ ![ Build Status] ( https://travis-ci.org/dart-lang/mockito.svg?branch=master )] ( https://travis-ci.org/dart-lang/mockito )
5
5
6
- Current mock libraries suffer from specifying method names as strings, which cause a lot of problems:
7
- * Poor refactoring support: rename method and you need manually search/replace it's usage in when/verify clauses.
8
- * Poor support from IDE: no code-completion, no hints on argument types, can't jump to definition
6
+ Current mock libraries suffer from specifying method names as strings, which
7
+ cause a lot of problems:
9
8
10
- Dart-mockito fixes it - stubbing and verifying are first-class citizens.
9
+ * Poor refactoring support: rename method and you need manually search/replace
10
+ it's usage in when/verify clauses.
11
+ * Poor support from IDE: no code-completion, no hints on argument types, can't
12
+ jump to definition
13
+
14
+ Dart's mockito package fixes these issues - stubbing and verifying are
15
+ first-class citizens.
11
16
12
17
## Let's create mocks
18
+
13
19
``` dart
14
20
import 'package:mockito/mockito.dart';
15
21
16
- //Real class
22
+ // Real class
17
23
class Cat {
18
24
String sound() => "Meow";
19
25
bool eatFood(String food, {bool hungry}) => true;
20
26
int walk(List<String> places);
21
- void sleep(){}
27
+ void sleep() {}
28
+ void hunt(String place, String prey) {}
22
29
int lives = 9;
23
30
}
24
31
25
- //Mock class
32
+ // Mock class
26
33
class MockCat extends Mock implements Cat {}
27
34
28
- //mock creation
35
+ // mock creation
29
36
var cat = new MockCat();
30
37
```
31
38
32
39
## Let's verify some behaviour!
40
+
33
41
``` dart
34
42
//using mock object
35
43
cat.sound();
36
44
//verify interaction
37
45
verify(cat.sound());
38
46
```
39
- Once created, mock will remember all interactions. Then you can selectively verify whatever interaction you are
40
- interested in.
47
+
48
+ Once created, mock will remember all interactions. Then you can selectively
49
+ verify whatever interaction you are interested in.
41
50
42
51
## How about some stubbing?
52
+
43
53
``` dart
44
- //unstubbed methods return null
54
+ // Unstubbed methods return null:
45
55
expect(cat.sound(), nullValue);
46
- //stubbing - before execution
56
+
57
+ // Stubbing - before execution:
47
58
when(cat.sound()).thenReturn("Purr");
48
59
expect(cat.sound(), "Purr");
49
- //you can call it again
60
+
61
+ // You can call it again:
50
62
expect(cat.sound(), "Purr");
51
- //let's change stub
63
+
64
+ // Let's change the stub:
52
65
when(cat.sound()).thenReturn("Meow");
53
66
expect(cat.sound(), "Meow");
54
- //you can stub getters
67
+
68
+ // You can stub getters:
55
69
when(cat.lives).thenReturn(9);
56
70
expect(cat.lives, 9);
57
- //you can stub a method to throw
71
+
72
+ // You can stub a method to throw:
58
73
when(cat.lives).thenThrow(new RangeError('Boo'));
59
74
expect(() => cat.lives, throwsRangeError);
60
- //we can calculate a response at call time:
75
+
76
+ // We can calculate a response at call time:
61
77
var responses = ["Purr", "Meow"];
62
78
when(cat.sound()).thenAnswer(() => responses.removeAt(0));
63
79
expect(cat.sound(), "Purr");
64
80
expect(cat.sound(), "Meow");
65
81
```
66
82
67
- By default, for all methods that return value, mock returns null.
68
- Stubbing can be overridden: for example common stubbing can go to fixture setup but the test methods can override it.
69
- Please note that overridding stubbing is a potential code smell that points out too much stubbing.
70
- Once stubbed, the method will always return stubbed value regardless of how many times it is called.
71
- Last stubbing is more important - when you stubbed the same method with the same arguments many times. Other words: the
72
- order of stubbing matters but it is only meaningful rarely, e.g. when stubbing exactly the same method calls or
73
- sometimes when argument matchers are used, etc.
83
+ By default, for all methods that return a value, ` mock ` returns ` null ` .
84
+ Stubbing can be overridden: for example common stubbing can go to fixture setup
85
+ but the test methods can override it. Please note that overridding stubbing is
86
+ a potential code smell that points out too much stubbing. Once stubbed, the
87
+ method will always return stubbed value regardless of how many times it is
88
+ called. Last stubbing is more important, when you stubbed the same method with
89
+ the same arguments many times. In other words: the order of stubbing matters,
90
+ but it is meaningful rarely, e.g. when stubbing exactly the same method calls
91
+ or sometimes when argument matchers are used, etc.
74
92
75
93
## Argument matchers
94
+
76
95
``` dart
77
- //you can use arguments itself...
96
+ // You can use arguments itself:
78
97
when(cat.eatFood("fish")).thenReturn(true);
79
- //..or collections
98
+
99
+ // ... or collections:
80
100
when(cat.walk(["roof","tree"])).thenReturn(2);
81
- //..or matchers
101
+
102
+ // ... or matchers:
82
103
when(cat.eatFood(argThat(startsWith("dry"))).thenReturn(false);
83
- //..or mix aguments with matchers
104
+
105
+ // ... or mix aguments with matchers:
84
106
when(cat.eatFood(argThat(startsWith("dry")), true).thenReturn(true);
85
107
expect(cat.eatFood("fish"), isTrue);
86
108
expect(cat.walk(["roof","tree"]), equals(2));
87
109
expect(cat.eatFood("dry food"), isFalse);
88
110
expect(cat.eatFood("dry food", hungry: true), isTrue);
89
- //you can also verify using an argument matcher
111
+
112
+ // You can also verify using an argument matcher:
90
113
verify(cat.eatFood("fish"));
91
114
verify(cat.walk(["roof","tree"]));
92
115
verify(cat.eatFood(argThat(contains("food"))));
93
- //you can verify setters
116
+
117
+ // You can verify setters:
94
118
cat.lives = 9;
95
119
verify(cat.lives=9);
96
120
```
97
- By default equals matcher is used to argument matching (since 0.11.0). It simplifies matching for collections as
98
- arguments. If you need more strict matching consider use ` argThat(identical(arg)) ` .
99
- Argument matchers allow flexible verification or stubbing
121
+
122
+ If an argument other than an ArgMatcher (like ` any ` , ` anyNamed() ` , ` argThat ` ,
123
+ ` captureArg ` , etc.) is passed to a mock method, then the ` equals ` matcher is
124
+ used for argument matching. If you need more strict matching consider use
125
+ ` argThat(identical(arg)) ` .
126
+
100
127
101
128
## Verifying exact number of invocations / at least x / never
129
+
102
130
``` dart
103
131
cat.sound();
104
132
cat.sound();
105
- //exact number of invocations
133
+
134
+ // Exact number of invocations:
106
135
verify(cat.sound()).called(2);
107
- //or using matcher
136
+
137
+ // Or using matcher:
108
138
verify(cat.sound()).called(greaterThan(1));
109
- //or never called
139
+
140
+ // Or never called:
110
141
verifyNever(cat.eatFood(any));
111
142
```
143
+
112
144
## Verification in order
145
+
113
146
``` dart
114
147
cat.eatFood("Milk");
115
148
cat.sound();
@@ -120,54 +153,64 @@ verifyInOrder([
120
153
cat.eatFood("Fish")
121
154
]);
122
155
```
123
- Verification in order is flexible - you don't have to verify all interactions one-by-one but only those that you are
124
- interested in testing in order.
156
+
157
+ Verification in order is flexible - you don't have to verify all interactions
158
+ one-by-one but only those that you are interested in testing in order.
125
159
126
160
## Making sure interaction(s) never happened on mock
161
+
127
162
``` dart
128
163
verifyZeroInteractions(cat);
129
164
```
130
165
131
166
## Finding redundant invocations
167
+
132
168
``` dart
133
169
cat.sound();
134
170
verify(cat.sound());
135
171
verifyNoMoreInteractions(cat);
136
172
```
137
173
138
174
## Capturing arguments for further assertions
175
+
139
176
``` dart
140
- //simple capture
177
+ // Simple capture:
141
178
cat.eatFood("Fish");
142
179
expect(verify(cat.eatFood(captureAny)).captured.single, "Fish");
143
- //capture multiple calls
180
+
181
+ // Capture multiple calls:
144
182
cat.eatFood("Milk");
145
183
cat.eatFood("Fish");
146
184
expect(verify(cat.eatFood(captureAny)).captured, ["Milk", "Fish"]);
147
- //conditional capture
185
+
186
+ // Conditional capture:
148
187
cat.eatFood("Milk");
149
188
cat.eatFood("Fish");
150
189
expect(verify(cat.eatFood(captureThat(startsWith("F")).captured, ["Fish"]);
151
190
```
152
191
153
192
## Waiting for an interaction
193
+
154
194
``` dart
155
- //waiting for a call
195
+ // Waiting for a call:
156
196
cat.eatFood("Fish");
157
197
await untilCalled(cat.chew()); //completes when cat.chew() is called
158
- //waiting for a call that has already happened
198
+
199
+ // Waiting for a call that has already happened:
159
200
cat.eatFood("Fish");
160
201
await untilCalled(cat.eatFood(any)); //will complete immediately
161
202
```
162
203
163
204
## Resetting mocks
205
+
164
206
``` dart
165
- //clearing collected interactions
207
+ // Clearing collected interactions:
166
208
cat.eatFood("Fish");
167
209
clearInteractions(cat);
168
210
cat.eatFood("Fish");
169
211
verify(cat.eatFood("Fish")).called(1);
170
- //resetting stubs and collected interactions
212
+
213
+ // Resetting stubs and collected interactions:
171
214
when(cat.eatFood("Fish")).thenReturn(true);
172
215
cat.eatFood("Fish");
173
216
reset(cat);
@@ -176,22 +219,28 @@ expect(cat.eatFood("Fish"), false);
176
219
```
177
220
178
221
## Spy
222
+
179
223
``` dart
180
- //spy creation
224
+ // Spy creation:
181
225
var cat = spy(new MockCat(), new Cat());
182
- //stubbing - before execution
226
+
227
+ // Stubbing - before execution:
183
228
when(cat.sound()).thenReturn("Purr");
184
- //using mocked interaction
185
- expect(cat.sound(), "Purr");
186
- //using real object
187
- expect(cat.lives, 9);
229
+
230
+ // Using mocked interaction:
231
+ expect(cat.sound(), "Purr");
232
+
233
+ // Using a real object:
234
+ expect(cat.lives, 9);
188
235
```
189
236
190
237
## Debugging
238
+
191
239
``` dart
192
- //print all collected invocations of any mock methods of a list of mock objects
240
+ // Print all collected invocations of any mock methods of a list of mock objects:
193
241
logInvocations([catOne, catTwo]);
194
- //throw every time that a mock method is called without a stub being matched
242
+
243
+ // Throw every time that a mock method is called without a stub being matched:
195
244
throwOnMissingStub(cat);
196
245
```
197
246
@@ -277,16 +326,18 @@ when(cat.eatFood(
277
326
[ Strong mode ] : https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md
278
327
279
328
## How it works
329
+
280
330
The basics of the ` Mock ` class are nothing special: It uses ` noSuchMethod ` to catch
281
331
all method invocations, and returns the value that you have configured beforehand with
282
332
` when() ` calls.
283
333
284
334
The implementation of ` when() ` is a bit more tricky. Take this example:
285
335
286
336
``` dart
287
- //unstubbed methods return null
337
+ // Unstubbed methods return null:
288
338
expect(cat.sound(), nullValue);
289
- //stubbing - before execution
339
+
340
+ // Stubbing - before execution:
290
341
when(cat.sound()).thenReturn("Purr");
291
342
```
292
343
@@ -306,6 +357,7 @@ The same goes for "chaining" mock objects in a test call. This will fail:
306
357
``` dart
307
358
var mockUtils = new MockUtils();
308
359
var mockStringUtils = new MockStringUtils();
360
+
309
361
// Setting up mockUtils.stringUtils to return a mock StringUtils implementation
310
362
when(mockUtils.stringUtils).thenReturn(mockStringUtils);
311
363
0 commit comments