@@ -25,61 +25,61 @@ interface Calculator {
25
25
isEnabled: boolean ;
26
26
}
27
27
28
- // Create:
29
- var calculator = Substitute .for <Calculator >();
28
+ // Create:
29
+ const calculator = Substitute .for <Calculator >();
30
30
31
- // Set a return value:
31
+ // Set a return value:
32
32
calculator .add (1 , 2 ).returns (3 );
33
33
34
- // Check received calls:
34
+ // Check received calls:
35
35
calculator .received ().add (1 , Arg .any ());
36
36
calculator .didNotReceive ().add (2 , 2 );
37
37
```
38
38
39
39
## Creating a mock
40
- ` var calculator = Substitute.for<Calculator>();`
40
+ ` const calculator = Substitute.for<Calculator>();`
41
41
42
42
## Setting return types
43
43
See the example below. The same syntax also applies to properties and fields.
44
44
45
45
``` typescript
46
- // single return type
46
+ // single return type
47
47
calculator .add (1 , 2 ).returns (4 );
48
- console .log (calculator .add (1 , 2 )); // prints 4
49
- console .log (calculator .add (1 , 2 )); // prints undefined
48
+ console .log (calculator .add (1 , 2 )); // prints 4
49
+ console .log (calculator .add (1 , 2 )); // prints undefined
50
50
51
- // multiple return types in sequence
51
+ // multiple return types in sequence
52
52
calculator .add (1 , 2 ).returns (3 , 7 , 9 );
53
- console .log (calculator .add (1 , 2 )); // prints 3
54
- console .log (calculator .add (1 , 2 )); // prints 7
55
- console .log (calculator .add (1 , 2 )); // prints 9
56
- console .log (calculator .add (1 , 2 )); // prints undefined
53
+ console .log (calculator .add (1 , 2 )); // prints 3
54
+ console .log (calculator .add (1 , 2 )); // prints 7
55
+ console .log (calculator .add (1 , 2 )); // prints 9
56
+ console .log (calculator .add (1 , 2 )); // prints undefined
57
57
```
58
58
59
59
## Working with promises
60
60
When working with promises you can also use ` resolves() ` and ` rejects() ` to return a promise.
61
61
62
62
``` typescript
63
63
calculator .heavyOperation (1 , 2 ).resolves (4 );
64
- // same as calculator.heavyOperation(1, 2).returns(Promise.resolve(4));
65
- console .log (await calculator .heavyOperation (1 , 2 )); // prints 4
64
+ // same as calculator.heavyOperation(1, 2).returns(Promise.resolve(4));
65
+ console .log (await calculator .heavyOperation (1 , 2 )); // prints 4
66
66
```
67
67
68
68
``` typescript
69
69
calculator .heavyOperation (1 , 2 ).rejects (new Error ());
70
- // same as calculator.heavyOperation(1, 2).returns(Promise.reject(new Error()));
71
- console .log (await calculator .heavyOperation (1 , 2 )); // throws Error
70
+ // same as calculator.heavyOperation(1, 2).returns(Promise.reject(new Error()));
71
+ console .log (await calculator .heavyOperation (1 , 2 )); // throws Error
72
72
```
73
73
74
74
## Verifying calls
75
75
``` typescript
76
76
calculator .enabled = true ;
77
- var foo = calculator .add (1 , 2 );
77
+ const foo = calculator .add (1 , 2 );
78
78
79
- // verify call to add(1, 2)
79
+ // verify call to add(1, 2)
80
80
calculator .received ().add (1 , 2 );
81
81
82
- // verify property set to "true"
82
+ // verify property set to "true"
83
83
calculator .received ().enabled = true ;
84
84
```
85
85
@@ -90,21 +90,38 @@ There are several ways of matching arguments. The examples below also applies to
90
90
``` typescript
91
91
import { Arg } from ' @fluffy-spoon/substitute' ;
92
92
93
- // ignoring first argument
93
+ // ignoring first argument
94
94
calculator .add (Arg .any (), 2 ).returns (10 );
95
- console .log (calculator .add (1337 , 3 )); // prints undefined since second argument doesn't match
96
- console .log (calculator .add (1337 , 2 )); // prints 10 since second argument matches
95
+ console .log (calculator .add (1337 , 3 )); // prints undefined since second argument doesn't match
96
+ console .log (calculator .add (1337 , 2 )); // prints 10 since second argument matches
97
97
98
- // received call with first arg 1 and second arg less than 0
98
+ // received call with first arg 1 and second arg less than 0
99
99
calculator .received ().add (1 , Arg .is (x => x < 0 ));
100
100
```
101
101
102
+ ### Generic and inverse matchers
103
+ ``` typescript
104
+ import { Arg } from ' @fluffy-spoon/substitute' ;
105
+
106
+ const equalToZero = (x : number ) => x === 0 ;
107
+
108
+ // first argument will match any number
109
+ // second argument will match a number that is not '0'
110
+ calculator .divide (Arg .any (' number' ), Arg .is .not (equalToZero )).returns (10 );
111
+ console .log (calculator .divide (100 , 10 )); // prints 10
112
+
113
+ const argIsNotZero = Arg .is .not (equalToZero );
114
+ calculator .received (1 ).divide (argIsNotZero , argIsNotZero );
115
+ ```
116
+
117
+ > #### Note: ` Arg.is() ` will automatically infer the type of the argument it's replacing
118
+
102
119
### Ignoring all arguments
103
120
``` typescript
104
- // ignoring all arguments
121
+ // ignoring all arguments
105
122
calculator .add (Arg .all ()).returns (10 );
106
- console .log (calculator .add (1 , 3 )); // prints 10
107
- console .log (calculator .add (5 , 2 )); // prints 10
123
+ console .log (calculator .add (1 , 3 )); // prints 10
124
+ console .log (calculator .add (5 , 2 )); // prints 10
108
125
```
109
126
110
127
### Match order
@@ -113,15 +130,15 @@ The order of argument matchers matters. The first matcher that matches will alwa
113
130
``` typescript
114
131
calculator .add (Arg .all ()).returns (10 );
115
132
calculator .add (1 , 3 ).returns (1337 );
116
- console .log (calculator .add (1 , 3 )); // prints 10
117
- console .log (calculator .add (5 , 2 )); // prints 10
133
+ console .log (calculator .add (1 , 3 )); // prints 10
134
+ console .log (calculator .add (5 , 2 )); // prints 10
118
135
```
119
136
120
137
``` typescript
121
138
calculator .add (1 , 3 ).returns (1337 );
122
139
calculator .add (Arg .all ()).returns (10 );
123
- console .log (calculator .add (1 , 3 )); // prints 1337
124
- console .log (calculator .add (5 , 2 )); // prints 10
140
+ console .log (calculator .add (1 , 3 )); // prints 1337
141
+ console .log (calculator .add (5 , 2 )); // prints 10
125
142
```
126
143
127
144
## Partial mocks
@@ -136,26 +153,26 @@ class RealCalculator implements Calculator {
136
153
divide(a : number , b : number ) => a / b ;
137
154
}
138
155
139
- var realCalculator = new RealCalculator ();
140
- var fakeCalculator = Substitute .for <Calculator >();
156
+ const realCalculator = new RealCalculator ();
157
+ const fakeCalculator = Substitute .for <Calculator >();
141
158
142
- // let the subtract method always use the real method
159
+ // let the subtract method always use the real method
143
160
fakeCalculator .subtract (Arg .all ()).mimicks (realCalculator .subtract );
144
- console .log (fakeCalculator .subtract (20 , 10 )); // prints 10
145
- console .log (fakeCalculator .subtract (1 , 2 )); // prints -1
161
+ console .log (fakeCalculator .subtract (20 , 10 )); // prints 10
162
+ console .log (fakeCalculator .subtract (1 , 2 )); // prints -1
146
163
147
- // for the add method, we only use the real method when the first arg is less than 10
148
- // else, we always return 1337
164
+ // for the add method, we only use the real method when the first arg is less than 10
165
+ // else, we always return 1337
149
166
fakeCalculator .add (Arg .is (x < 10 ), Arg .any ()).mimicks (realCalculator .add );
150
167
fakeCalculator .add (Arg .is (x >= 10 ), Arg .any ()).returns (1337 );
151
- console .log (fakeCalculator .add (5 , 100 )); // prints 105 via real method
152
- console .log (fakeCalculator .add (210 , 7 )); // prints 1337 via fake method
168
+ console .log (fakeCalculator .add (5 , 100 )); // prints 105 via real method
169
+ console .log (fakeCalculator .add (210 , 7 )); // prints 1337 via fake method
153
170
154
- // for the divide method, we only use the real method for explicit arguments
171
+ // for the divide method, we only use the real method for explicit arguments
155
172
fakeCalculator .divide (10 , 2 ).mimicks (realCalculator .divide );
156
173
fakeCalculator .divide (Arg .all ()).returns (1338 );
157
- console .log (fakeCalculator .divide (10 , 5 )); // prints 5
158
- console .log (fakeCalculator .divide (9 , 5 )); // prints 1338
174
+ console .log (fakeCalculator .divide (10 , 5 )); // prints 5
175
+ console .log (fakeCalculator .divide (9 , 5 )); // prints 1338
159
176
```
160
177
161
178
## Throwing exceptions
@@ -196,15 +213,15 @@ class Example {
196
213
}
197
214
}
198
215
199
- var fake = Substitute .for <Example >();
216
+ const fake = Substitute .for <Example >();
200
217
201
- // BAD: this would have called substitute.js' "received" method.
202
- // fake.received(2);
218
+ // BAD: this would have called substitute.js' "received" method.
219
+ // fake.received(2);
203
220
204
- // GOOD: we now call the "received" method we have defined in the class above.
221
+ // GOOD: we now call the "received" method we have defined in the class above.
205
222
Substitute .disableFor (fake ).received (1337 );
206
223
207
- // now we can assert that we received a call to the "received" method.
224
+ // now we can assert that we received a call to the "received" method.
208
225
fake .received ().received (1337 );
209
226
```
210
227
0 commit comments