Add notes to CHANGELOG and NULL_SAFETY_README re: fallback generators
Also add another test for fallback generators
Also bump to 5.0.9
PiperOrigin-RevId: 375738620
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 425c521..af40c6a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,17 @@
-## 5.0.9-dev
+## 5.0.9
* Mock classes now implement a type's nested type arguments properly.
[#410](https://github.com/dart-lang/mockito/issues/410)
+* Mock classes now implement API from a class's interface(s) (in addition to
+ superclasses and mix ins). Thanks @markgravity.
+ [#404](https://github.com/dart-lang/mockito/pull/404)
+* A MockSpec passed into a `@GenerateMocks` annotation's `customMocks` list can
+ now specify "fallback generators." These are functions which can be used to
+ generate fake responses that mockito's code generation needs in order to
+ return a value for a method with a generic return type. See
+ [NULL_SAFETY_README][] for details.
+
+[NULL_SAFETY_README]: https://github.com/dart-lang/mockito/blob/master/NULL_SAFETY_README.md
## 5.0.8
diff --git a/NULL_SAFETY_README.md b/NULL_SAFETY_README.md
index 50a2def..2b6eecf 100644
--- a/NULL_SAFETY_README.md
+++ b/NULL_SAFETY_README.md
@@ -156,6 +156,46 @@
@GenerateMocks([], customMocks: [MockSpec<Foo>(returnNullOnMissingStub: true)])
```
+#### Fallback generators
+
+If a class has a method with a type variable as a return type (for example,
+`T get<T>();`), mockito cannot generate code which will internally return valid
+values. For example, given this class and test:
+
+```dart
+abstract class Foo {
+ T m<T>(T a);
+}
+
+@GenerateMocks([], customMocks: [MockSpec<Foo>(as: #MockFoo, {#m: mShim})])
+void testFoo(Foo foo) {
+ when( foo.m(7) ).thenReturn(42);
+ // ^^^^^^^^
+ // mockito needs a valid value which this call to `foo.m` will return.
+}
+```
+
+In order to generate a mock for such a class, pass a `fallbackGenerators`
+argument. Specify a mapping from the method to a top level function with the
+same signature as the method:
+
+```dart
+abstract class Foo {
+ T m<T>(T a);
+}
+
+T mShim<T>(T a) {
+ if (a is int) return 1;
+ throw 'unknown';
+}
+
+@GenerateMocks([], customMocks: [MockSpec<Foo>(as: #MockFoo, {#m: mShim})])
+```
+
+The fallback values will never be returned from a real method call; these are
+not stub return values. They are only used internally by mockito as valid return
+values.
+
### Manual mock implementaion
**In the general case, we strongly recommend generating mocks with the above
diff --git a/lib/src/version.dart b/lib/src/version.dart
index b3ae609..e141d2d 100644
--- a/lib/src/version.dart
+++ b/lib/src/version.dart
@@ -1 +1 @@
-const packageVersion = '5.0.8';
+const packageVersion = '5.0.9';
diff --git a/pubspec.yaml b/pubspec.yaml
index 4366865..0d719cd 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: mockito
-version: 5.0.8
+version: 5.0.9
description: A mock framework inspired by Mockito.
homepage: https://github.com/dart-lang/mockito
diff --git a/test/builder/custom_mocks_test.dart b/test/builder/custom_mocks_test.dart
index 2e4301c..f4c6340 100644
--- a/test/builder/custom_mocks_test.dart
+++ b/test/builder/custom_mocks_test.dart
@@ -321,6 +321,39 @@
test(
'generates mock classes including a dummy builder for a generic method '
+ 'with positional parameters returning a Future of the generic', () async {
+ var mocksContent = await buildWithNonNullable({
+ ...annotationsAsset,
+ 'foo|lib/foo.dart': dedent(r'''
+ abstract class Foo {
+ Future<T> m<T>(T a);
+ }
+ '''),
+ 'foo|test/foo_test.dart': '''
+ import 'package:foo/foo.dart';
+ import 'package:mockito/annotations.dart';
+
+ Future<T> mShim<T>(T a) async {
+ if (a is int) return 1;
+ throw 'unknown';
+ }
+
+ @GenerateMocks(
+ [],
+ customMocks: [MockSpec<Foo>(as: #MockFoo, fallbackGenerators: {#m: mShim})],
+ )
+ void main() {}
+ '''
+ });
+ expect(
+ mocksContent,
+ contains(
+ '_i3.Future<T> m<T>(T? a) => (super.noSuchMethod(Invocation.method(#m, [a]),\n'
+ ' returnValue: _i4.mShim<T>(a)) as _i3.Future<T>)'));
+ });
+
+ test(
+ 'generates mock classes including a dummy builder for a generic method '
'with named parameters', () async {
var mocksContent = await buildWithNonNullable({
...annotationsAsset,