@@ -3,113 +3,146 @@ Mock library for Dart inspired by [Mockito](https://github.com/mockito/mockito).
33[ ![ Pub] ( https://img.shields.io/pub/v/mockito.svg )] ( )
44[ ![ Build Status] ( https://travis-ci.org/dart-lang/mockito.svg?branch=master )] ( https://travis-ci.org/dart-lang/mockito )
55
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:
98
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.
1116
1217## Let's create mocks
18+
1319``` dart
1420import 'package:mockito/mockito.dart';
1521
16- //Real class
22+ // Real class
1723class Cat {
1824 String sound() => "Meow";
1925 bool eatFood(String food, {bool hungry}) => true;
2026 int walk(List<String> places);
21- void sleep(){}
27+ void sleep() {}
28+ void hunt(String place, String prey) {}
2229 int lives = 9;
2330}
2431
25- //Mock class
32+ // Mock class
2633class MockCat extends Mock implements Cat {}
2734
28- //mock creation
35+ // mock creation
2936var cat = new MockCat();
3037```
3138
3239## Let's verify some behaviour!
40+
3341``` dart
3442//using mock object
3543cat.sound();
3644//verify interaction
3745verify(cat.sound());
3846```
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.
4150
4251## How about some stubbing?
52+
4353``` dart
44- //unstubbed methods return null
54+ // Unstubbed methods return null:
4555expect(cat.sound(), nullValue);
46- //stubbing - before execution
56+
57+ // Stubbing - before execution:
4758when(cat.sound()).thenReturn("Purr");
4859expect(cat.sound(), "Purr");
49- //you can call it again
60+
61+ // You can call it again:
5062expect(cat.sound(), "Purr");
51- //let's change stub
63+
64+ // Let's change the stub:
5265when(cat.sound()).thenReturn("Meow");
5366expect(cat.sound(), "Meow");
54- //you can stub getters
67+
68+ // You can stub getters:
5569when(cat.lives).thenReturn(9);
5670expect(cat.lives, 9);
57- //you can stub a method to throw
71+
72+ // You can stub a method to throw:
5873when(cat.lives).thenThrow(new RangeError('Boo'));
5974expect(() => cat.lives, throwsRangeError);
60- //we can calculate a response at call time:
75+
76+ // We can calculate a response at call time:
6177var responses = ["Purr", "Meow"];
6278when(cat.sound()).thenAnswer(() => responses.removeAt(0));
6379expect(cat.sound(), "Purr");
6480expect(cat.sound(), "Meow");
6581```
6682
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.
7492
7593## Argument matchers
94+
7695``` dart
77- //you can use arguments itself...
96+ // You can use arguments itself:
7897when(cat.eatFood("fish")).thenReturn(true);
79- //..or collections
98+
99+ // ... or collections:
80100when(cat.walk(["roof","tree"])).thenReturn(2);
81- //..or matchers
101+
102+ // ... or matchers:
82103when(cat.eatFood(argThat(startsWith("dry"))).thenReturn(false);
83- //..or mix aguments with matchers
104+
105+ // ... or mix aguments with matchers:
84106when(cat.eatFood(argThat(startsWith("dry")), true).thenReturn(true);
85107expect(cat.eatFood("fish"), isTrue);
86108expect(cat.walk(["roof","tree"]), equals(2));
87109expect(cat.eatFood("dry food"), isFalse);
88110expect(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:
90113verify(cat.eatFood("fish"));
91114verify(cat.walk(["roof","tree"]));
92115verify(cat.eatFood(argThat(contains("food"))));
93- //you can verify setters
116+
117+ // You can verify setters:
94118cat.lives = 9;
95119verify(cat.lives=9);
96120```
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+
100127
101128## Verifying exact number of invocations / at least x / never
129+
102130``` dart
103131cat.sound();
104132cat.sound();
105- //exact number of invocations
133+
134+ // Exact number of invocations:
106135verify(cat.sound()).called(2);
107- //or using matcher
136+
137+ // Or using matcher:
108138verify(cat.sound()).called(greaterThan(1));
109- //or never called
139+
140+ // Or never called:
110141verifyNever(cat.eatFood(any));
111142```
143+
112144## Verification in order
145+
113146``` dart
114147cat.eatFood("Milk");
115148cat.sound();
@@ -120,54 +153,64 @@ verifyInOrder([
120153 cat.eatFood("Fish")
121154]);
122155```
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.
125159
126160## Making sure interaction(s) never happened on mock
161+
127162``` dart
128163 verifyZeroInteractions(cat);
129164```
130165
131166## Finding redundant invocations
167+
132168``` dart
133169cat.sound();
134170verify(cat.sound());
135171verifyNoMoreInteractions(cat);
136172```
137173
138174## Capturing arguments for further assertions
175+
139176``` dart
140- //simple capture
177+ // Simple capture:
141178cat.eatFood("Fish");
142179expect(verify(cat.eatFood(captureAny)).captured.single, "Fish");
143- //capture multiple calls
180+
181+ // Capture multiple calls:
144182cat.eatFood("Milk");
145183cat.eatFood("Fish");
146184expect(verify(cat.eatFood(captureAny)).captured, ["Milk", "Fish"]);
147- //conditional capture
185+
186+ // Conditional capture:
148187cat.eatFood("Milk");
149188cat.eatFood("Fish");
150189expect(verify(cat.eatFood(captureThat(startsWith("F")).captured, ["Fish"]);
151190```
152191
153192## Waiting for an interaction
193+
154194``` dart
155- //waiting for a call
195+ // Waiting for a call:
156196cat.eatFood("Fish");
157197await 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:
159200cat.eatFood("Fish");
160201await untilCalled(cat.eatFood(any)); //will complete immediately
161202```
162203
163204## Resetting mocks
205+
164206``` dart
165- //clearing collected interactions
207+ // Clearing collected interactions:
166208cat.eatFood("Fish");
167209clearInteractions(cat);
168210cat.eatFood("Fish");
169211verify(cat.eatFood("Fish")).called(1);
170- //resetting stubs and collected interactions
212+
213+ // Resetting stubs and collected interactions:
171214when(cat.eatFood("Fish")).thenReturn(true);
172215cat.eatFood("Fish");
173216reset(cat);
@@ -176,22 +219,28 @@ expect(cat.eatFood("Fish"), false);
176219```
177220
178221## Spy
222+
179223``` dart
180- //spy creation
224+ // Spy creation:
181225var cat = spy(new MockCat(), new Cat());
182- //stubbing - before execution
226+
227+ // Stubbing - before execution:
183228when(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);
188235```
189236
190237## Debugging
238+
191239``` 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:
193241logInvocations([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:
195244throwOnMissingStub(cat);
196245```
197246
@@ -277,16 +326,18 @@ when(cat.eatFood(
277326[ Strong mode ] : https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md
278327
279328## How it works
329+
280330The basics of the ` Mock ` class are nothing special: It uses ` noSuchMethod ` to catch
281331all method invocations, and returns the value that you have configured beforehand with
282332` when() ` calls.
283333
284334The implementation of ` when() ` is a bit more tricky. Take this example:
285335
286336``` dart
287- //unstubbed methods return null
337+ // Unstubbed methods return null:
288338expect(cat.sound(), nullValue);
289- //stubbing - before execution
339+
340+ // Stubbing - before execution:
290341when(cat.sound()).thenReturn("Purr");
291342```
292343
@@ -306,6 +357,7 @@ The same goes for "chaining" mock objects in a test call. This will fail:
306357``` dart
307358var mockUtils = new MockUtils();
308359var mockStringUtils = new MockStringUtils();
360+
309361// Setting up mockUtils.stringUtils to return a mock StringUtils implementation
310362when(mockUtils.stringUtils).thenReturn(mockStringUtils);
311363
0 commit comments