### Test Setup with Mockito Annotations Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Sets up a test file to use Mockito's code generation for mocks. Requires importing annotations and the generated mocks library. ```dart import 'package:mockito/annotations.dart'; import 'package:test/test.dart'; import 'http_server.dart'; @GenerateNiceMocks([MockSpec()]) import 'http_server_test.mocks.dart'; void main() { test('test', () { var httpServer = MockHttpServer(); // We want to stub the `start` method. }); } ``` -------------------------------- ### Manual Mock Implementation Example Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Demonstrates overriding methods with non-nullable parameters or return types in a manual mock implementation. Parameters are made nullable, and `super.noSuchMethod` is called with an Invocation object. ```dart class HttpServer { void start(int port) { ... } Uri get uri { ... } } class MockHttpServer extends Mock implements HttpServer {} ``` -------------------------------- ### Chaining Mock Objects Example (Fails) Source: https://github.com/dart-archive/mockito/blob/master/FAQ.md This example demonstrates a common pitfall when verifying chained mock objects. `verify` can interfere with the mocked return values. ```dart var mockUtils = MockUtils(); var mockStringUtils = MockStringUtils(); when(mockUtils.stringUtils).thenReturn(mockStringUtils); // FAILS! verify(mockUtils.stringUtils.uppercase()).called(1); // Instead use this: verify(mockStringUtils.uppercase()).called(1); ``` -------------------------------- ### Custom Mock Class Name with MockSpec Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Example of using `as` in `MockSpec` to specify a custom name for the generated mock class, useful for avoiding name collisions. ```dart @GenerateNiceMocks([MockSpec(as: #BaseMockFoo)]) ``` -------------------------------- ### Clean Global Mockito State with resetMockitoState Source: https://context7.com/dart-archive/mockito/llms.txt Call `resetMockitoState` in `setUp` or `tearDown` to clear all global Mockito state, preventing cross-test pollution. This includes flags, matchers, captured arguments, and dummy builders. ```dart import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; import 'package:mockito/annotations.dart'; @GenerateNiceMocks([MockSpec()]) import 'http_client_test.mocks.dart'; abstract class HttpClient { Future get(String url); } void main() { setUp(() { // Guarantees a clean slate regardless of what previous tests did resetMockitoState(); }); test('stub from setUp is clean', () async { final client = MockHttpClient(); when(client.get(any)) .thenAnswer((_) async => '{"status": "ok"}'); final body = await client.get('https://api.example.com/health'); expect(body, contains('ok')); }); } ``` -------------------------------- ### Writing a Fake Class Source: https://github.com/dart-archive/mockito/blob/master/README.md Shows how to create a fake object by extending `Fake` and implementing specific methods. Unimplemented methods will throw `UnimplementedError` by default, but can be overridden. ```dart // Fake class class FakeCat extends Fake implements Cat { @override bool eatFood(String food, {bool? hungry}) { print('Fake eat $food'); return true; } } void main() { // Create a new fake Cat at runtime. var cat = FakeCat(); cat.eatFood("Milk"); // Prints 'Fake eat Milk'. cat.sleep(); // Throws. } ``` -------------------------------- ### Add Mockito and build_runner to pubspec.yaml Source: https://context7.com/dart-archive/mockito/llms.txt Include `mockito` and `build_runner` as dev dependencies in your `pubspec.yaml` file. ```yaml # pubspec.yaml dev_dependencies: mockito: ^5.6.3 build_runner: ^2.5.0 test: ^1.24.4 ``` -------------------------------- ### Stubbing and Verifying a Mocked Getter Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Demonstrates how to stub and verify a mocked getter using `when` and `verify`. The return value specified during stubbing is ignored during stubbing/verification but used during actual calls. ```dart var httpServer = MockHttpServer(); when(httpServer.uri).thenReturn(Uri.http('dart.dev', '/')); httpServer.uri; verify(httpServer.uri).called(1); ``` -------------------------------- ### Nice Mocks vs Classic Mocks Behavior Source: https://github.com/dart-archive/mockito/blob/master/README.md Illustrates the difference in behavior between mocks generated with `@GenerateNiceMocks` (returns simple legal values for unstubbed calls) and `@GenerateMocks` (throws an exception for unstubbed calls). `@GenerateNiceMocks` is recommended. ```dart void main() { var cat = MockCat(); cat.sound(); } ``` -------------------------------- ### Reset Mock State with reset and clearInteractions Source: https://context7.com/dart-archive/mockito/llms.txt `reset` clears both stubs and recorded interactions. `clearInteractions` clears only the recorded interactions (call history), leaving stubs intact. Use `clearInteractions` to reset call counts without reconfiguring stubs, and `reset` to start fresh. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; @GenerateNiceMocks([MockSpec()]) import 'token_store_test.mocks.dart'; abstract class TokenStore { String? getToken(String userId); void saveToken(String userId, String token); } void main() { late MockTokenStore store; setUp(() { store = MockTokenStore(); when(store.getToken(any)).thenReturn('initial-token'); }); test('clearInteractions preserves stubs', () { store.getToken('user1'); clearInteractions(store); // Stub still works expect(store.getToken('user2'), 'initial-token'); // Only the call after clearInteractions is counted verify(store.getToken('user2')).called(1); }); test('reset removes both stubs and history', () { store.getToken('user1'); reset(store); when(store.getToken('user1')).thenReturn('new-token'); expect(store.getToken('user1'), 'new-token'); verifyNever(store.saveToken(any, any)); }); } ``` -------------------------------- ### Running build_runner to Generate Mocks Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Commands to execute build_runner to generate the mock classes based on the annotations in your test files. ```shell dart run build_runner build ``` -------------------------------- ### Mockito 1.x with Typed Wrapper (Dart 2 Interim Solution) Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Shows the interim solution for Dart 2 compatibility in Mockito 1.x, using the 'typed' function to wrap ArgumentMatchers. ```dart when(cat.eatFood( typed(argThat(contains('mouse'))), hungry: typed(any, named: 'hungry')))... ``` -------------------------------- ### Mocking a Function Type Source: https://github.com/dart-archive/mockito/blob/master/README.md Demonstrates how to mock function types by defining an abstract class with the desired method signatures. These methods can then be torn off, stubbed, and verified. ```dart @GenerateMocks([Cat, Callbacks]) import 'cat_test.mocks.dart' abstract class Callbacks { Cat findCat(String name); } void main() { var mockCat = MockCat(); var findCatCallback = MockCallbacks().findCat; when(findCatCallback('Pete')).thenReturn(mockCat); } ``` -------------------------------- ### Customizing Mock Output with build.yaml Source: https://github.com/dart-archive/mockito/blob/master/FAQ.md Configure mock generation paths using `build_extensions` in `build.yaml`. Ensure patterns cover all input files and the output always ends with `.mocks.dart`. ```yaml targets: $default: builders: mockito|mockBuilder: generate_for: options: build_extensions: '^tests/{{}}.dart' : 'tests/mocks/{{}}.mocks.dart' '^integration-tests/{{}}.dart' : 'integration-tests/{{}}.mocks.dart' ``` -------------------------------- ### Migrate Positional Argument Matchers to Mockito 3 Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Shows how to use argument matchers as positional arguments. Mockito 3 simplifies the syntax by removing the need for `typed()`. ```dart when(obj.fn(typed(any)))... ``` ```dart when(obj.fn(any))... ``` -------------------------------- ### Upgrade Named Arguments: any Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Shows how to update the usage of 'any' with named arguments in Mockito 3. The argument name must be specified as a string. ```dart foo: anyNamed('foo') ``` -------------------------------- ### Generate Nice Mocks with @GenerateNiceMocks Source: https://context7.com/dart-archive/mockito/llms.txt Use `@GenerateNiceMocks` to create mock classes that return sensible default values for unstubbed methods. This is recommended for most use cases. ```dart // payment_service_test.dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; import 'payment_service.dart'; @GenerateNiceMocks([MockSpec()]) import 'payment_service_test.mocks.dart'; // Real classes to mock abstract class PaymentGateway { Future charge(String customerId, int amountCents); String get apiVersion; } void main() { late MockPaymentGateway gateway; setUp(() => gateway = MockPaymentGateway()); test('returns default values without stubs (nice mock behavior)', () { // No stub set — nice mock returns '' for String getter expect(gateway.apiVersion, ''); }); } ``` -------------------------------- ### Implement Manual Test Doubles with Fake Source: https://context7.com/dart-archive/mockito/llms.txt Use `Fake` to create partial implementations of interfaces, providing real logic for a subset of methods. Unimplemented methods will throw `UnimplementedError`. ```dart import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; abstract class FileStorage { String read(String path); void write(String path, String content); bool exists(String path); } // Fake in-memory implementation for testing class FakeFileStorage extends Fake implements FileStorage { final Map _files = {}; @override String read(String path) => _files[path] ?? (throw Exception('File not found: $path')); @override void write(String path, String content) => _files[path] = content; @override bool exists(String path) => _files.containsKey(path); } void main() { test('FakeFileStorage behaves like real storage', () { final storage = FakeFileStorage(); storage.write('/tmp/hello.txt', 'Hello, World!'); expect(storage.exists('/tmp/hello.txt'), true); expect(storage.read('/tmp/hello.txt'), 'Hello, World!'); expect(() => storage.read('/nonexistent'), throwsException); }); } ``` -------------------------------- ### Mockito 1.x API (Dart 1) Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Illustrates the Mockito 1.x API usage, which was not type-safe for Dart 2 and passed ArgumentMatchers directly. ```dart when(cat.eatFood(argThat(contains('mouse')), hungry: any))... ``` -------------------------------- ### Migrate Positional argThat Matchers to Mockito 3 Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Demonstrates migrating `argThat` with `equals` for positional arguments. Mockito 3 removes the `typed()` wrapper. ```dart when(obj.fn(typed(argThat(equals(7)))))... ``` ```dart when(obj.fn(argThat(equals(7))))... ``` -------------------------------- ### Stubbing Synchronous Methods and Getters with `when`/`thenReturn` Source: https://context7.com/dart-archive/mockito/llms.txt Use `when` and `thenReturn` to provide canned responses for mock methods and getters. The last matching stub takes precedence. Stubs persist until `reset()` is called. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; @GenerateNiceMocks([MockSpec()]) import 'calculator_test.mocks.dart'; abstract class Calculator { int add(int a, int b); String format(int value); int get lastResult; } void main() { test('stubbing methods and getters', () { final calc = MockCalculator(); // Stub a method with fixed args when(calc.add(2, 3)).thenReturn(5); expect(calc.add(2, 3), 5); // Stub a getter when(calc.lastResult).thenReturn(42); expect(calc.lastResult, 42); // Last stub wins when multiple stubs match when(calc.add(2, 3)).thenReturn(99); expect(calc.add(2, 3), 99); // Unmatched call returns nice-mock default (0 for int) expect(calc.add(1, 1), 0); }); test('thenReturnInOrder — sequential responses', () { final calc = MockCalculator(); when(calc.add(any, any)).thenReturnInOrder([10, 20, 30]); expect(calc.add(1, 1), 10); expect(calc.add(2, 2), 20); expect(calc.add(3, 3), 30); // 4th call throws StateError — no more answers expect(() => calc.add(4, 4), throwsStateError); }); } ``` -------------------------------- ### Argument Matchers for Flexible Stubbing and Verification Source: https://context7.com/dart-archive/mockito/llms.txt Argument matchers like `any`, `anyNamed`, `argThat`, and `captureThat` allow for flexible matching of arguments during stubbing and verification. Ensure named argument matchers include the parameter name. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; @GenerateNiceMocks([MockSpec()]) import 'search_engine_test.mocks.dart'; abstract class SearchEngine { List search(String query, {int limit, String? filter}); bool index(String docId, Map data); } void main() { test('argument matchers in stubbing', () { final engine = MockSearchEngine(); // any — matches any positional argument when(engine.search(any, limit: anyNamed('limit'))) .thenReturn(['result1', 'result2']); // argThat — matches using a Matcher when(engine.search(argThat(startsWith('dart:')))) .thenReturn(['dart:core', 'dart:io']); expect(engine.search('anything', limit: 10), ['result1', 'result2']); expect(engine.search('dart:async'), ['dart:core', 'dart:io']); }); test('capturing arguments for assertion', () { final engine = MockSearchEngine(); when(engine.index(any, any)).thenReturn(true); engine.index('doc1', {'title': 'Hello'}); engine.index('doc2', {'title': 'World'}); // captureAny — captures the actual values final result = verify(engine.index(captureAny, captureAny)); // captured is a flat list: [docId1, data1, docId2, data2] expect(result.captured, [ 'doc1', {'title': 'Hello'}, 'doc2', {'title': 'World'}, ]); }); } ``` -------------------------------- ### Upgrade Null Arguments Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Explains how to replace bare 'null' arguments with 'argThat(isNull)' for compatibility with Mockito 3. ```dart argThat(isNull) ``` -------------------------------- ### Upgrade Named Arguments: argThat Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Demonstrates the required change for 'argThat' when used with named arguments in Mockito 3. The argument name must be provided. ```dart foo: argThat(..., named: 'foo') ``` -------------------------------- ### Migrate Named Argument Matchers to Mockito 3 Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Illustrates the change in syntax for using named argument matchers. Mockito 3 introduces `anyNamed` and removes the `typed()` wrapper. ```dart when(obj.fn(foo: typed(any, named: 'foo')))... ``` ```dart when(obj.fn(foo: anyNamed('foo')))... ``` -------------------------------- ### Mockito 3.0.0-alpha+4 API Changes Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Highlights the specific API changes introduced in Mockito 3.0.0-alpha+4 to maintain backward compatibility with Mockito 2.x. ```diff -argThat(Matcher matcher) => new ArgMatcher(matcher, false); +argThat(Matcher matcher, {String named}) => new ArgMatcher(matcher, false); -captureThat(Matcher matcher) => new ArgMatcher(matcher, true); +captureThat(Matcher matcher, {String named}) => new ArgMatcher(matcher, true); +anyNamed(String named) => typed(any, named: named); +captureAnyNamed(String named) => typed(captureAny, named: named); ``` -------------------------------- ### Verify Method Calls in Order Source: https://github.com/dart-archive/mockito/blob/master/README.md Use `verifyInOrder` to assert that a sequence of method calls occurred in a specific order. This is useful for testing scenarios where the order of operations is critical. ```dart cat.eatFood("Milk"); cat.sound(); cat.eatFood("Fish"); verifyInOrder([ cat.eatFood("Milk"), cat.sound(), cat.eatFood("Fish") ]); ``` -------------------------------- ### Debug Mock Invocations with logInvocations Source: https://context7.com/dart-archive/mockito/llms.txt Use `logInvocations` to print all recorded invocations across multiple mocks, sorted by timestamp. This aids in debugging mock behavior and call history. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @GenerateNiceMocks([MockSpec(), MockSpec()]) import 'debug_test.mocks.dart'; abstract class ServiceA { void doA(String arg); } abstract class ServiceB { int doB(int x); } void main() { final a = MockServiceA(); final b = MockServiceB(); a.doA('first'); b.doB(1); a.doA('second'); b.doB(2); // Prints all calls interleaved and sorted by time: // MockServiceA.doA('first') // MockServiceB.doB(1) // MockServiceA.doA('second') // MockServiceB.doB(2) logInvocations([a, b]); } ``` -------------------------------- ### Upgrade Named Arguments: captureThat Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Shows the updated usage of 'captureThat' with named arguments in Mockito 3, where the argument name must be explicitly provided. ```dart foo: captureThat(..., named: 'foo') ``` -------------------------------- ### Generate Mocks with build_runner Source: https://context7.com/dart-archive/mockito/llms.txt Use `dart run build_runner build` to generate mock files after annotating your test files. Use `dart run build_runner watch` for continuous regeneration during development. ```shell # Generate mocks after annotating test files dart run build_runner build # Watch mode for continuous regeneration during development dart run build_runner watch ``` -------------------------------- ### Standard Mockito Stubbing (Pre-Null Safety) Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Shows the typical way to stub a method on a Mockito mock object. Note: This is illegal under null safety. ```dart var server = MockHttpServer(); var uri = Uri.parse('http://localhost:8080'); when(server.start(any)).thenReturn(uri); ``` -------------------------------- ### Verify Method Call Once and Capture Arguments Source: https://github.com/dart-archive/mockito/blob/master/FAQ.md Verify a method call once and capture its arguments for further assertions. This is useful when you need to inspect the exact values passed to a mocked method. ```dart cat.eatFood("fish"); verify(cat.eatFood("fish")); // This call succeeds. verify(cat.eatFood(any)); // This call fails. ``` -------------------------------- ### Upgrade Named Arguments: captureAny Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Illustrates the syntax update for 'captureAny' with named arguments in Mockito 3, requiring the argument name as a string. ```dart foo: captureAnyNamed('foo') ``` -------------------------------- ### Register Custom Dummy Values with provideDummy Source: https://context7.com/dart-archive/mockito/llms.txt Use `provideDummy` to register default values for types Mockito cannot generate automatically. This is crucial for nice mocks returning custom non-nullable types. `provideDummyBuilder` offers context-aware dummy generation. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; // A custom non-nullable value type class UserId { final String value; const UserId(this.value); } @GenerateNiceMocks([MockSpec()]) import 'user_repo_test.mocks.dart'; abstract class UserRepo { UserId currentUserId(); List listUserIds(); } void main() { setUp(() { // Register a dummy so nice mocks can return something for UserId provideDummy(const UserId('dummy')); // Or use a builder for context-aware dummies provideDummyBuilder((parent, inv) => UserId('dummy-from-${inv.memberName}')); }); test('nice mock returns dummy for unstubbed UserId method', () { final repo = MockUserRepo(); // No stub — returns the registered dummy final id = repo.currentUserId(); expect(id.value, startsWith('dummy')); }); test('stub overrides dummy', () { final repo = MockUserRepo(); when(repo.currentUserId()).thenReturn(const UserId('real-user')); expect(repo.currentUserId().value, 'real-user'); }); } ``` -------------------------------- ### Log Mock Invocations Source: https://github.com/dart-archive/mockito/blob/master/README.md Use `logInvocations` to print all collected method calls made on a list of mock objects. This is helpful for debugging and understanding mock behavior. ```dart // Print all collected invocations of any mock methods of a list of mock objects: logInvocations([catOne, catTwo]); ``` -------------------------------- ### Verify Method Call Count and Capture Arguments Source: https://github.com/dart-archive/mockito/blob/master/FAQ.md Verify the number of times a method was called and capture arguments from each call. This allows for detailed analysis of method invocation frequency and arguments used. ```dart cat.hunt("home", "birds"); cat.hunt("home", "lizards"); var verification = verify(cat.hunt("home", captureAny)); verification.called(greaterThan(2)); var firstCall = verification.captured[0]; var secondCall = verification.captured[1]; expect(firstCall, equals(["birds"])); expect(secondCall, equals(["lizards"])); ``` -------------------------------- ### Migrate Named Null Matchers to Mockito 3 Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Details the migration for matching null values with named arguments. Mockito 3.0.0-alpha+4 uses `typedArgThat(isNull, ...)` and Mockito 3.0 uses `argThat(isNull, ...)`. ```dart when(obj.fn(foo: typed(null, named: 'foo')))... ``` ```dart when(obj.fn(foo: typedArgThat(isNull, named: 'foo')))... ``` ```dart when(obj.fn(foo: argThat(isNull, named: 'foo')))... ``` -------------------------------- ### Mocking Generic Classes with Type Arguments Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Demonstrates how to generate a mock for a generic class by specifying the type arguments within `MockSpec`. ```dart @GenerateNiceMocks([MockSpec>(as: #MockFooOfInt)]) ``` -------------------------------- ### Standard Mockito Mock Class Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Defines a basic mock class for HttpServer using Mockito's `Mock` and `implements`. ```dart class MockHttpServer extends Mock implements HttpServer {} ``` -------------------------------- ### Argument Matchers in Mockito Source: https://github.com/dart-archive/mockito/blob/master/README.md Mockito's `ArgMatcher` allows capturing arguments and tracking named arguments. Various matchers like `any`, `argThat`, and `captureThat` can be used. ```dart // You can use `any` when(cat.eatFood(any)).thenReturn(false); // ... or plain arguments themselves when(cat.eatFood("fish")).thenReturn(true); // ... including collections when(cat.walk(["roof","tree"])).thenReturn(2); // ... or matchers when(cat.eatFood(argThat(startsWith("dry")))).thenReturn(false); // ... or mix arguments with matchers when(cat.eatFood(argThat(startsWith("dry")), hungry: true)).thenReturn(true); expect(cat.eatFood("fish"), isTrue); expect(cat.walk(["roof","tree"])), equals(2)); expect(cat.eatFood("dry food"), isFalse); expect(cat.eatFood("dry food", hungry: true), isTrue); ``` ```dart // You can also verify using an argument matcher. verify(cat.eatFood("fish")); verify(cat.walk(["roof","tree"])); verify(cat.eatFood(argThat(contains("food")))); ``` ```dart // You can verify setters. cat.lives = 9; verify(cat.lives=9); ``` ```dart verify(cat.hunt("backyard", null)); // OK: no arg matchers. verify(cat.hunt(argThat(contains("yard")), null)); // BAD: adjacent null. verify(cat.hunt(argThat(contains("yard")), argThat(isNull))); // OK: wrapped in an arg matcher. verify(cat.eatFood("Milk", hungry: null)); // BAD: null as a named argument. verify(cat.eatFood("Milk", hungry: argThat(isNull))); // BAD: null as a named argument. ``` -------------------------------- ### Opt-in Strict Mode with throwOnMissingStub Source: https://context7.com/dart-archive/mockito/llms.txt Converts a generated nice mock to a strict mock, causing unstubbed calls to throw `MissingStubError` at runtime. An optional custom exception builder can be provided for tailored error handling. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; @GenerateNiceMocks([MockSpec()]) import 'notifier_test.mocks.dart'; abstract class Notifier { void push(String channel, String message); bool isConnected(String channel); } void main() { test('throwOnMissingStub converts nice mock to strict', () { final notifier = MockNotifier(); throwOnMissingStub(notifier); // Now acts like a strict mock — unstubbed call throws expect(() => notifier.isConnected('ws://push'), throwsA(isA())); }); test('custom exception builder', () { final notifier = MockNotifier(); throwOnMissingStub( notifier, exceptionBuilder: (inv) => throw StateError( 'Unstubbed: ${inv.memberName}', ), ); expect(() => notifier.push('ch', 'msg'), throwsStateError); }); } ``` -------------------------------- ### Generate Mock Classes with @GenerateNiceMocks Source: https://github.com/dart-archive/mockito/blob/master/README.md Use the @GenerateNiceMocks annotation to direct Mockito's code generation. This creates a mock class for each specified 'real' class in a new library. Ensure build_runner is added as a dev dependency. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; // Annotation which generates the cat.mocks.dart library and the MockCat class. @GenerateNiceMocks([MockSpec()]) import 'cat.mocks.dart'; // Real class class Cat { String sound() => "Meow"; bool eatFood(String food, {bool? hungry}) => true; Future chew() async => print("Chewing..."); int walk(List places) => 7; void sleep() {} void hunt(String place, String prey) {} int lives = 9; } void main() { // Create mock object. var cat = MockCat(); } ``` -------------------------------- ### Migrate Named argThat Matchers to Mockito 3 Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Shows the updated syntax for `argThat` with named arguments. Mockito 3.0.0-alpha+4 introduced `typedArgThat`, while Mockito 3.0 uses `argThat` directly. ```dart when(obj.fn(foo: typed(argThat(equals(7)), named: 'foo')))... ``` ```dart when(obj.fn(foo: typedArgThat(equals(7), named: 'foo')))... ``` ```dart when(obj.fn(foo: argThat(equals(7), named: 'foo')))... ``` -------------------------------- ### Test ISS Visibility (Visible Scenario) Source: https://github.com/dart-archive/mockito/blob/master/example/iss/README.md Tests the IssSpotter to verify if the ISS is visible from a given observer location. It stubs the IssLocator.currentPosition to return a predefined ISS location and asserts that isVisible is true. ```dart group('ISS spotter', () { test('ISS visible', () async { Point sf = new Point(37.783333, -122.416667); Point mtv = new Point(37.389444, -122.081944); IssLocator locator = new MockIssLocator(); // Mountain View should be visible from San Francisco. when(locator.currentPosition).thenReturn(sf); var spotter = new IssSpotter(locator, mtv); expect(spotter.isVisible, true); }); ``` -------------------------------- ### Migrate Named captureAny to Mockito 3 Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Shows the updated syntax for capturing any named argument. Mockito 3.0.0-alpha+4 uses `captureAnyNamed`, while Mockito 3.0 uses the same. ```dart when(obj.fn(foo: typed(captureAny, named: 'foo')))... ``` ```dart when(obj.fn(foo: captureAnyNamed('foo')))... ``` -------------------------------- ### Capture Arguments with captureAny and captureThat Source: https://context7.com/dart-archive/mockito/llms.txt Use `captureThat` with a matcher to capture specific arguments, and `captureAny` for any argument. Useful for asserting on actual values passed to mock methods during verification. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; @GenerateNiceMocks([MockSpec()]) import 'event_bus_test.mocks.dart'; abstract class EventBus { void emit(String eventType, Map payload); } void main() { test('capture and inspect emitted event payloads', () { final bus = MockEventBus(); bus.emit('order.created', {'orderId': 'abc', 'amount': 99}); bus.emit('order.shipped', {'orderId': 'abc', 'carrier': 'FedEx'}); // Capture only events that start with 'order.' final result = verify( bus.emit(captureThat(startsWith('order.')), captureAny), ); expect(result.captured[0], 'order.created'); expect(result.captured[1], containsPair('orderId', 'abc')); expect(result.captured[2], 'order.shipped'); expect(result.captured[3], containsPair('carrier', 'FedEx')); result.called(2); }); } ``` -------------------------------- ### Manual Mock Implementation with Null Safety Source: https://context7.com/dart-archive/mockito/llms.txt Implement mock classes manually by overriding methods with non-nullable parameter or return types, forwarding to `super.noSuchMethod` with appropriate `returnValue` fallbacks. This approach is useful when code generation is not available or desired. ```dart import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; abstract class HttpServer { Uri start(int port); void stop(); } // Manual mock — no code generation needed class MockHttpServer extends Mock implements HttpServer { @override Uri start(int? port) => super.noSuchMethod( Invocation.method(#start, [port]), returnValue: Uri.http('localhost', '/'), ) as Uri; @override void stop() => super.noSuchMethod(Invocation.method(#stop, [])); } void main() { test('manual mock stubs and verifies correctly', () { final server = MockHttpServer(); final fakeUri = Uri.parse('http://localhost:8080'); when(server.start(8080)).thenReturn(fakeUri); expect(server.start(8080), fakeUri); verify(server.start(8080)).called(1); verifyNever(server.stop()); }); } ``` -------------------------------- ### Mockito 3.x API (Dart 2 Safe) Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Demonstrates the simplified and type-safe Mockito 3.x API, which removes the 'typed' wrapper and uses 'anyNamed' for named arguments. ```dart when(cat.eatFood(argThat(contains('mouse')), hungry: anyNamed('hungry')))... ``` -------------------------------- ### Throw on Missing Stub Source: https://github.com/dart-archive/mockito/blob/master/README.md Use `throwOnMissingStub` to configure a mock object to throw an exception whenever a method is called without a matching stub. This helps in identifying missing stub configurations during testing. ```dart // Throw every time that a mock method is called without a stub being matched: throwOnMissingStub(cat); ``` -------------------------------- ### Test ISS Visibility (Not Visible Scenario) Source: https://github.com/dart-archive/mockito/blob/master/example/iss/README.md Tests the IssSpotter to verify if the ISS is not visible from a given observer location. It stubs the IssLocator.currentPosition to return a predefined ISS location and asserts that isVisible is false. ```dart test('ISS not visible', () async { Point london = new Point(51.5073, -0.1277); Point mtv = new Point(37.389444, -122.081944); IssLocator locator = new MockIssLocator(); // London should not be visible from Mountain View. when(locator.currentPosition).thenReturn(london); var spotter = new IssSpotter(locator, mtv); expect(spotter.isVisible, false); }); }); ``` -------------------------------- ### Verifying Invocation Counts Source: https://github.com/dart-archive/mockito/blob/master/README.md Use `verify` or `verifyNever` to check the number of times a mock method was called. This includes exact counts, minimum counts, or ensuring a method was never called. ```dart cat.sound(); cat.sound(); // Exact number of invocations verify(cat.sound()).called(2); // Or using matcher verify(cat.sound()).called(greaterThan(1)); // Or never called verifyNever(cat.eatFood(any)); ``` -------------------------------- ### Migrate Named captureThat to Mockito 3 Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Illustrates the migration for capturing a named argument that matches a condition. Mockito 3.0.0-alpha+4 uses `typedCaptureThat`, while Mockito 3.0 uses `captureThat` directly. ```dart when(obj.fn(foo: typed(captureThat(equals(7)), named: 'foo')))... ``` ```dart when(obj.fn(foo: typedCaptureThat(equals(7), named: 'foo')))... ``` ```dart when(obj.fn(foo: captureThat(equals(7), named: 'foo')))... ``` -------------------------------- ### Verifying Method Calls with `verify` Source: https://context7.com/dart-archive/mockito/llms.txt Assert that a mock method was called with specific arguments or a certain number of times. Each `verify` call marks interactions as verified. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; @GenerateNiceMocks([MockSpec()]) import 'email_sender_test.mocks.dart'; abstract class EmailSender { void send(String to, String subject, String body); void sendBulk(List recipients, String subject); } void main() { test('verify send was called with exact arguments', () { final sender = MockEmailSender(); when(sender.send(any, any, any)).thenReturn(null); sender.send('alice@example.com', 'Welcome', 'Hello Alice!'); verify(sender.send('alice@example.com', 'Welcome', 'Hello Alice!')); }); test('verify call count', () { final sender = MockEmailSender(); sender.send('a@b.com', 'Hi', 'Body'); sender.send('a@b.com', 'Hi', 'Body'); sender.send('a@b.com', 'Hi', 'Body'); verify(sender.send('a@b.com', 'Hi', 'Body')).called(3); verify(sender.send(any, any, any)).called(greaterThanOrEqualTo(1)); }); } ``` -------------------------------- ### Exhaustive Verification with verifyZeroInteractions and verifyNoMoreInteractions Source: https://context7.com/dart-archive/mockito/llms.txt `verifyZeroInteractions` asserts that no calls were made to a mock at all. `verifyNoMoreInteractions` asserts that all recorded calls to a mock have been verified. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; @GenerateNiceMocks([MockSpec(), MockSpec()]) import 'cache_db_test.mocks.dart'; abstract class Cache { String? get(String key); void set(String key, String value); } abstract class Database { String query(String sql); } void main() { test('cache hit prevents database access', () { final cache = MockCache(); final db = MockDatabase(); when(cache.get('user:1')).thenReturn('{"id":1}'); final result = cache.get('user:1'); expect(result, '{"id":1}'); verify(cache.get('user:1')); // Database must not have been touched verifyZeroInteractions(db); }); test('verifyNoMoreInteractions after all expected calls', () { final cache = MockCache(); when(cache.get(any)).thenReturn(null); cache.get('key1'); cache.get('key2'); verify(cache.get('key1')); verify(cache.get('key2')); verifyNoMoreInteractions(cache); }); } ``` -------------------------------- ### Capture Arguments from Verified Method Call Source: https://github.com/dart-archive/mockito/blob/master/FAQ.md Capture arguments from a verified method call to make multiple assertions on those arguments. This avoids the limitation of a call being marked as 'verified' after its first verification. ```dart cat.hunt("home", "birds"); var captured = verify(cat.hunt(captureAny, captureAny)).captured.single; expect(captured[0], equals("home")); expect(captured[1], equals("birds")); ``` -------------------------------- ### Stub Mock Methods with when() Source: https://github.com/dart-archive/mockito/blob/master/README.md Use the when() API to stub mock methods before interaction. This allows you to define the return value or behavior of a method call. The last declared stub for a method takes precedence. ```dart // Stub a mock method before interacting. when(cat.sound()).thenReturn("Purr"); expect(cat.sound(), "Purr"); // You can call it again. expect(cat.sound(), "Purr"); // Let's change the stub. when(cat.sound()).thenReturn("Meow"); expect(cat.sound(), "Meow"); // You can stub getters. when(cat.lives).thenReturn(9); expect(cat.lives, 9); // You can stub a method to throw. when(cat.lives).thenThrow(RangeError('Boo')); expect(() => cat.lives, throwsRangeError); // We can calculate a response at call time. var responses = ["Purr", "Meow"]; when(cat.sound()).thenAnswer((_) => responses.removeAt(0)); expect(cat.sound(), "Purr"); expect(cat.sound(), "Meow"); // We can stub a method with multiple calls that happened in a particular order. when(cat.sound()).thenReturnInOrder(["Purr", "Meow"]); expect(cat.sound(), "Purr"); expect(cat.sound(), "Meow"); expect(() => cat.sound(), throwsA(isA())); ``` -------------------------------- ### Mocking with Unsupported Members Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Use `unsupportedMembers` to generate a mock class with overrides that throw UnsupportedError for specified members. This ensures the mock class is a valid implementation, though not useful at runtime. ```dart @GenerateNiceMocks([ MockSpec(unsupportedMembers: {#method}), ]) ``` -------------------------------- ### Async Stubbing with thenAnswer Source: https://github.com/dart-archive/mockito/blob/master/README.md Use `thenAnswer` for stubbing methods that return a `Future` or `Stream` to avoid unexpected behavior. `thenReturn` is not suitable for these cases. ```dart // BAD when(mock.methodThatReturnsAFuture()) .thenReturn(Future.value('Stub')); when(mock.methodThatReturnsAStream()) .thenReturn(Stream.fromIterable(['Stub'])); // GOOD when(mock.methodThatReturnsAFuture()) .thenAnswer((_) async => 'Stub'); when(mock.methodThatReturnsAStream()) .thenAnswer((_) => Stream.fromIterable(['Stub'])); ``` ```dart // Use the above method unless you're sure you want to create the Future ahead // of time. final future = Future.value('Stub'); when(mock.methodThatReturnsAFuture()).thenAnswer((_) => future); ``` -------------------------------- ### Verify Mock Interactions Source: https://github.com/dart-archive/mockito/blob/master/README.md After creating a mock object, you can verify that specific interactions occurred. Mockito's verify function records and checks method calls on the mock. ```dart // Interact with the mock object. cat.sound(); // Verify the interaction. verify(cat.sound()); ``` -------------------------------- ### Custom Mock Specification with MockSpec Source: https://context7.com/dart-archive/mockito/llms.txt Use `MockSpec` for fine-grained control over mock generation, including custom names, fallback generators for generic types, and unsupported members. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; // Source class with generic method abstract class Repository { T findById(String id); List listAll(); } // Fallback generator for generic return type T T repoFindByIdShim(String? id) => throw UnimplementedError(); @GenerateNiceMocks([ // Custom name to avoid collision MockSpec(as: #MockRepo), // Fallback generator for the generic method MockSpec( as: #MockRepoWithFallback, fallbackGenerators: {#findById: repoFindByIdShim}, ), // Unsupported member — throws UnsupportedError instead of returning dummy MockSpec( as: #MockRepoStrict, unsupportedMembers: {#findById}, ), ]) import 'mock_spec_example.mocks.dart'; ``` -------------------------------- ### Refactor to Accept Object Instead of Constructing Source: https://github.com/dart-archive/mockito/blob/master/FAQ.md Refactor code to accept an object as a parameter instead of constructing it directly. This pattern facilitates mocking in tests by allowing you to pass in a mock object. ```dart // BEFORE: void f() { var foo = Foo(); // ... } // AFTER void f(Foo foo) { // ... } ``` -------------------------------- ### Remove Typed Wrapper: any Source: https://github.com/dart-archive/mockito/blob/master/upgrading-to-mockito-3.md Demonstrates removing the 'typed' wrapper when used with 'any' in Mockito 3, simplifying the syntax. ```dart any ``` -------------------------------- ### Generate Mocks with Classic Exception Behavior Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Uses `@GenerateMocks` to create mock classes that throw an exception when a method is called without a corresponding stub, mimicking older Mockito behavior. ```dart @GenerateMocks([Foo]) ``` -------------------------------- ### Stubbing Dynamic Responses and Async Methods with `thenAnswer` Source: https://context7.com/dart-archive/mockito/llms.txt Use `thenAnswer` to compute return values dynamically based on the invocation. This is required for `Future` and `Stream` return types. It receives the real `Invocation` object. ```dart import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; @GenerateNiceMocks([MockSpec()]) import 'data_source_test.mocks.dart'; abstract class DataSource { Future fetchUser(String id); Stream watchCount(); int transform(int input); } void main() { test('thenAnswer for async methods', () async { final ds = MockDataSource(); // Future stub — must use thenAnswer when(ds.fetchUser(any)) .thenAnswer((inv) async { final id = inv.positionalArguments[0] as String; return '{"id": "$id", "name": "Alice"}'; }); final result = await ds.fetchUser('u123'); expect(result, contains('"id": "u123"')); }); test('thenAnswer for Stream', () async { final ds = MockDataSource(); when(ds.watchCount()) .thenAnswer((_) => Stream.fromIterable([1, 2, 3])); final values = await ds.watchCount().toList(); expect(values, [1, 2, 3]); }); test('thenAnswer for dynamic computation', () { final ds = MockDataSource(); when(ds.transform(any)) .thenAnswer((inv) => (inv.positionalArguments[0] as int) * 2); expect(ds.transform(5), 10); expect(ds.transform(7), 14); }); } ``` -------------------------------- ### Capture Arguments for Assertions Source: https://github.com/dart-archive/mockito/blob/master/README.md Use `captureAny`, `captureThat`, and `captureAnyNamed` to capture arguments passed to mock methods for further assertions. This is useful for verifying specific values or patterns in arguments. ```dart // Simple capture cat.eatFood("Fish"); expect(verify(cat.eatFood(captureAny)).captured.single, "Fish"); ``` ```dart // Capture multiple calls cat.eatFood("Milk"); cat.eatFood("Fish"); expect(verify(cat.eatFood(captureAny)).captured, ["Milk", "Fish"]); ``` ```dart // Conditional capture cat.eatFood("Milk"); cat.eatFood("Fish"); expect(verify(cat.eatFood(captureThat(startsWith("F")))).captured, ["Fish"]); ``` -------------------------------- ### Mock IssLocator Class Definition Source: https://github.com/dart-archive/mockito/blob/master/example/iss/README.md Defines a mock class for IssLocator using Mockito's noSuchMethod for intercepting method invocations. This is used in unit tests to simulate the behavior of the IssLocator. ```dart // The Mock class uses noSuchMethod to catch all method invocations. class MockIssLocator extends Mock implements IssLocator {} ``` -------------------------------- ### Test Spherical Distance Calculation Source: https://github.com/dart-archive/mockito/blob/master/example/iss/README.md Tests the sphericalDistanceKm function by calculating the distance between two predefined points on Earth. Asserts that the calculated distance is within a specified tolerance. ```dart group('Spherical distance', () { test('London - Paris', () { Point london = new Point(51.5073, -0.1277); Point paris = new Point(48.8566, 2.3522); double d = sphericalDistanceKm(london, paris); // London should be approximately 343.5km // (+/- 0.1km) from Paris. expect(d, closeTo(343.5, 0.1)); }); test('San Francisco - Mountain View', () { Point sf = new Point(37.783333, -122.416667); Point mtv = new Point(37.389444, -122.081944); double d = sphericalDistanceKm(sf, mtv); // San Francisco should be approximately 52.8km // (+/- 0.1km) from Mountain View. expect(d, closeTo(52.8, 0.1)); }); }); ``` -------------------------------- ### Stubbing a Mock Method in Dart Source: https://github.com/dart-archive/mockito/blob/master/FAQ.md Use `when().thenReturn()` to define the return value for a mock method before it's called. Unstubbed methods return null. ```dart expect(cat.sound(), nullValue); when(cat.sound()).thenReturn("Purr"); ``` -------------------------------- ### Non-nullable types in Dart Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Illustrates a Dart class with non-nullable method parameters and return types, which are common in null-safe Dart. ```dart class HttpServer { Uri start(int port) { // ... } } ``` -------------------------------- ### Mocking with Fallback Generators Source: https://github.com/dart-archive/mockito/blob/master/NULL_SAFETY_README.md Utilize `fallbackGenerators` to provide a top-level function for members returning non-nullable type variables. The function must match the member's signature, with nullable parameters, to generate a more useful mock implementation. ```dart @GenerateNiceMocks([ MockSpec(as: #MockFoo, fallbackGenerators: {#m: mShim}) ]) abstract class Foo { T m(T a, int b); } T mShim(T a, int? b) { if (a is int) return 1; throw 'unknown'; } ```