|
1 | 1 | # Frequently asked questions
|
2 | 2 |
|
3 |
| -#### How do I mock a static method, constructor, or top-level function? |
| 3 | +## How do I mock a static method, constructor, or top-level function? |
4 | 4 |
|
5 | 5 | Mockito provides its stubbing and verification features by overriding class
|
6 | 6 | instance methods. Since there is no mechanism for overriding static methods,
|
@@ -58,12 +58,12 @@ for production and a [MemoryFileSystem] for tests), and use its wrapper methods
|
58 | 58 | [io package]: https://pub.dev/packages/io
|
59 | 59 | [ProcessManager]: https://pub.dev/documentation/io/latest/io/ProcessManager-class.html
|
60 | 60 |
|
61 |
| -#### How do I mock an extension method? |
| 61 | +## How do I mock an extension method? |
62 | 62 |
|
63 | 63 | If there is no way to override some kind of function, then mockito cannot mock
|
64 | 64 | it. See the above answer for further explanation, and alternatives.
|
65 | 65 |
|
66 |
| -#### Why can a method call not be verified multiple times? |
| 66 | +## Why can a method call not be verified multiple times? |
67 | 67 |
|
68 | 68 | When mockito verifies a method call (via [`verify`] or [`verifyInOrder`]), it
|
69 | 69 | marks the call as "verified", which excludes the call from further
|
@@ -100,7 +100,7 @@ expect(firstCall, equals(["birds"]));
|
100 | 100 | expect(secondCall, equals(["lizards"]));
|
101 | 101 | ```
|
102 | 102 |
|
103 |
| -#### How does mockito work? |
| 103 | +## How does mockito work? |
104 | 104 |
|
105 | 105 | The basics of the `Mock` class are nothing special: It uses `noSuchMethod` to
|
106 | 106 | catch all method invocations, and returns the value that you have configured
|
@@ -169,7 +169,7 @@ it's done. It's very straightforward.
|
169 | 169 | [`verifyInOrder`]: https://pub.dev/documentation/mockito/latest/mockito/verifyInOrder.html
|
170 | 170 |
|
171 | 171 |
|
172 |
| -### How can I customize where Mockito outputs its mocks? |
| 172 | +## How can I customize where Mockito outputs its mocks? |
173 | 173 |
|
174 | 174 | Mockito supports configuration of outputs by the configuration provided by the `build`
|
175 | 175 | package by creating (if it doesn't exist already) the `build.yaml` at the root folder
|
@@ -203,3 +203,71 @@ targets:
|
203 | 203 | ```
|
204 | 204 |
|
205 | 205 | Also, you can also check out the example configuration in the Mockito repository.
|
| 206 | + |
| 207 | + |
| 208 | +## How do I mock a `sealed` class? |
| 209 | + |
| 210 | +Suppose that you have code such as: |
| 211 | + |
| 212 | +```dart |
| 213 | +class Bar { |
| 214 | + int value; |
| 215 | +
|
| 216 | + Bar(this.value); |
| 217 | +
|
| 218 | + Bar.zero() : value = 0; |
| 219 | +} |
| 220 | +
|
| 221 | +class Foo { |
| 222 | + Bar someMethod(int value) => Bar(value); |
| 223 | +} |
| 224 | +``` |
| 225 | + |
| 226 | +and now you want to mock `Foo`. The generated implementation for `MockFoo` |
| 227 | +needs to return *something* if `someMethod` is called. It can't return `null` |
| 228 | +since its return type is non-nullable. It can't construct a `Bar` on its own |
| 229 | +without understanding the semantics of `Bar`'s constructors. That is, which |
| 230 | +`Bar` constructor should be called and with what arguments? To avoid this, |
| 231 | +Mockito instead generates its own, fake implementation of `Bar` that it does |
| 232 | +know how to construct, something like: |
| 233 | + |
| 234 | +```dart |
| 235 | +class _FakeBar extends Fake implements Bar {} |
| 236 | +``` |
| 237 | + |
| 238 | +And then the generated implementation of `MockFoo` can have its `someMethod` |
| 239 | +override return a `_FakeBar` instance. |
| 240 | + |
| 241 | +However, if `Bar` is `sealed` (or is marked with `base` or `final`), then it |
| 242 | +cannot be `implemented` in generated code. Therefore Mockito can't generate a |
| 243 | +default value for a `Bar` on its own, and it needs users to specify the default |
| 244 | +value to use via `provideDummy` or `provideDummyBuilder`: |
| 245 | + |
| 246 | +```dart |
| 247 | +import 'package:mockito/annotations.dart'; |
| 248 | +import 'package:mockito/mockito.dart'; |
| 249 | +
|
| 250 | +@GenerateNiceMocks([MockSpec<Foo>()]) |
| 251 | +import 'foo.mocks.dart'; |
| 252 | +
|
| 253 | +sealed class Bar { |
| 254 | + int value; |
| 255 | +
|
| 256 | + Bar(this.value); |
| 257 | +
|
| 258 | + Bar.zero() : value = 0; |
| 259 | +} |
| 260 | +
|
| 261 | +class Foo { |
| 262 | + Bar someMethod(int value) => Bar(value); |
| 263 | +} |
| 264 | +
|
| 265 | +void main() { |
| 266 | + provideDummy(Bar.zero()); |
| 267 | +
|
| 268 | + var mockFoo = MockFoo(); |
| 269 | +} |
| 270 | +``` |
| 271 | + |
| 272 | +Note that the value used as the "dummy" usually doesn't matter since methods on |
| 273 | +the mock typically will be stubbed, overriding the method's return value. |
0 commit comments