You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+74-12Lines changed: 74 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,6 +23,8 @@ The library has independent developers, release cycle and versioning from core m
23
23
* Repositories: [Maven Central](https://search.maven.org/search?q=mockito-scala) or [JFrog's Bintray](https://bintray.com/mockito/maven/mockito-scala)
24
24
25
25
26
+
## Note: For more examples and use cases than the ones shown below, please refer to the library's [tests](https://github.com/mockito/mockito-scala/blob/master/core/src/test)
Inspired by [this](https://stackoverflow.com/questions/51387234/is-there-a-per-test-non-specific-mock-reset-pattern-using-scalaplayspecmockito) StackOverflow question,
143
153
mockito-scala provides this trait that helps to automatically reset any existent mock after each test is run
144
154
The trait has to be mixed **after**`org.mockito.MockitoSugar` in order to work, otherwise your test will not compile
145
155
The code shown in the StackOverflow question would look like this if using this mechanism
146
156
157
+
NOTE: MockitoFixture and ResetMocksAfterEachTest are mutually exclusive, so don't expect them to work together
@@ -206,6 +218,56 @@ As you can see the new syntax reads a bit more natural, also notice you can use
206
218
207
219
Check the [tests](https://github.com/mockito/mockito-scala/blob/master/core/src/test/scala/org/mockito/IdiomaticMockitoTest.scala) for more examples
208
220
221
+
## Default Answers
222
+
We defined a new type `org.mockito.DefaultAnswer` which is used to configure the default behaviour of a mock when a non-stubbed invocation
223
+
is made on it, the default behaviour is different to the Java version, instead of returning null for any non-primitive or non-final class,
224
+
mockito-scala will return a "Smart Null", which is basically a mock of the type returned by the called method.
225
+
The main advantage of this is that if the code tries to call any method on this mock, instead of failing with a NPE we will
226
+
throw a different exception with a hint of the non-stubbed method call (including its params) that returned this Smart Null,
227
+
this will make it much easier to find and fix a non-stubbed call
228
+
229
+
Most of the Answers defined in `org.mockito.Answers` have it's counterpart as a `org.mockito.DefaultAnswer`, and on top of that
230
+
we also provide `org.mockito.ReturnsEmptyValues` which will try its best to return an empty object for well known types,
231
+
i.e. `Nil` for `List`, `None` for `Option` etc.
232
+
This DefaultAnswer is not part of the default behaviour as we think a SmartNull is better, to explain why, let's imagine we
testObj.get(123) shouldBe Some(Json(....)) //overly simplified for clarity
251
+
}
252
+
}
253
+
}
254
+
```
255
+
256
+
Now, in that example that test could fail in 3 different ways
257
+
258
+
1) With the standard implementation of Mockito, the mock would return null and we would get a NullPointerException, which we all agree it's far from ideal, as it's hard to know where did it happen in non trivial code
259
+
2) With the default/empty values, we would get a `None`, so the final result would be `None` and we will get an assertion error as `None` is not `Some(Json(....))`, but I'm not sure how much improvement over the NPE this would be, because in a non-trivial method we may have many dependencies returning `Option` and it could be hard to track down which one is returning `None` and why
260
+
3) With a smart-null, we would return a `mock[Option]` and as soon as our code calls to `.map()` that mock would fail with an exception telling you what non-stubbed method was called and on which mock (in the example would say something you called the `find` method on some `mock of type UserRepository`)
261
+
262
+
And that's why we use option 3 as default
263
+
264
+
Of course you can override the default behaviour, for this you have 2 options
265
+
266
+
1) If you wanna do it just for a particular mock, you can, at creation time do `mock[MyType](MyDefaultAnswer)`
267
+
2) If you wanna do it for all the mocks in a test, you can define an `implicit`, i.e. `implicit val defaultAnswer: DefaultAnswer = MyDefaultAnswer`
268
+
269
+
DefaultAnswers are also composable, so for example if you wanted empty values first and then smart nulls you could do `implicit val defaultAnswer: DefaultAnswer = ReturnsEmptyValues orElse ReturnsSmartNulls`
270
+
209
271
## Experimental features
210
272
211
273
***by-name** arguments is currently an experimental feature as the implementation is a bit hacky and it gave some people problems
0 commit comments