Add type annotations to Future dummy return values.
These allow the `as` cast to succeed; otherwise it is guaranteed to fail.
Fixes https://github.com/dart-lang/mockito/issues/380
PiperOrigin-RevId: 367907501
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d490d9a..0d7afb4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 5.0.4
+
+* Allow calling methods with void return types w/o stubbing.
+ [#367](https://github.com/dart-lang/mockito/issues/367)
+* Add type argument to dummy `Future` return value.
+ [#380](https://github.com/dart-lang/mockito/issues/380)
+
## 5.0.3
* Support 1.x releases of source_gen.
diff --git a/lib/src/builder.dart b/lib/src/builder.dart
index 47a8dd0..0f7da31 100644
--- a/lib/src/builder.dart
+++ b/lib/src/builder.dart
@@ -872,7 +872,7 @@
if (method.returnType.isVoid) {
returnValueForMissingStub = refer('null');
} else if (method.returnType.isFutureOfVoid) {
- returnValueForMissingStub = refer('Future').property('value').call([]);
+ returnValueForMissingStub = _futureReference().property('value').call([]);
}
final namedArgs = {
if (_returnTypeIsNonNullable(method))
@@ -912,7 +912,7 @@
} else if (interfaceType.isDartAsyncFuture ||
interfaceType.isDartAsyncFutureOr) {
var typeArgument = typeArguments.first;
- return refer('Future')
+ return _futureReference(_typeReference(typeArgument))
.property('value')
.call([_dummyValue(typeArgument)]);
} else if (interfaceType.isDartCoreInt) {
@@ -952,6 +952,15 @@
return _dummyValueImplementing(type as analyzer.InterfaceType);
}
+ /// Returns a reference to [Future], optionally with a type argument for the
+ /// value of the Future.
+ TypeReference _futureReference([Reference valueType]) => TypeReference((b) {
+ b.symbol = 'Future';
+ if (valueType != null) {
+ b.types.add(valueType);
+ }
+ });
+
Expression _dummyFunctionValue(analyzer.FunctionType type) {
return Method((b) {
// The positional parameters in a FunctionType have no names. This
diff --git a/lib/src/version.dart b/lib/src/version.dart
index 977890f..2c9f52f 100644
--- a/lib/src/version.dart
+++ b/lib/src/version.dart
@@ -1 +1 @@
-const packageVersion = '5.0.3';
+const packageVersion = '5.0.4';
diff --git a/pubspec.yaml b/pubspec.yaml
index dff34bf..543d0b6 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: mockito
-version: 5.0.3
+version: 5.0.4
description: A mock framework inspired by Mockito.
homepage: https://github.com/dart-lang/mockito
diff --git a/test/builder/auto_mocks_test.dart b/test/builder/auto_mocks_test.dart
index d69317d..e1e53f4 100644
--- a/test/builder/auto_mocks_test.dart
+++ b/test/builder/auto_mocks_test.dart
@@ -524,7 +524,7 @@
'''),
_containsAllOf(dedent2('''
_i3.Future<void> m() => (super.noSuchMethod(Invocation.method(#m, []),
- returnValue: Future.value(null),
+ returnValue: Future<void>.value(null),
returnValueForMissingStub: Future.value()) as _i3.Future<void>);
''')),
);
@@ -1779,7 +1779,25 @@
'''),
_containsAllOf(dedent2('''
_i3.Future<bool> m() => (super.noSuchMethod(Invocation.method(#m, []),
- returnValue: Future.value(false)) as _i3.Future<bool>);
+ returnValue: Future<bool>.value(false)) as _i3.Future<bool>);
+ ''')),
+ );
+ });
+
+ test(
+ 'creates dummy non-null return values for Futures of known generic core classes',
+ () async {
+ await expectSingleNonNullableOutput(
+ dedent(r'''
+ class Foo {
+ Future<Iterable<bool>> m() async => false;
+ }
+ '''),
+ _containsAllOf(dedent2('''
+ _i3.Future<Iterable<bool>> m() =>
+ (super.noSuchMethod(Invocation.method(#m, []),
+ returnValue: Future<Iterable<bool>>.value([]))
+ as _i3.Future<Iterable<bool>>);
''')),
);
});