Skip to content

Commit

Permalink
Generate valid functions with optional non-nullable arguments
Browse files Browse the repository at this point in the history
If a method of a mocked class returns a function with optional
yet non-nullable argument, Mockito currently produces something
like
```dart
(int x, {int y}) => /* doesn't matter */
```
which is not a valid Dart, since `y` must either be `required` or
have a default value. `required` won't fit into the desired type
and coming up with a default value is not easy, since it has to
be a constant, but `dummyValue` doesn't always produce one.

Fortunately, we can just widen the type here and make it nullable.

PiperOrigin-RevId: 582669927
  • Loading branch information
Ilya Yanok authored and copybara-github committed Nov 15, 2023
1 parent fcb9779 commit dc3eb65
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 4 deletions.
5 changes: 3 additions & 2 deletions lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1580,12 +1580,13 @@ class _MockClassInfo {
} else if (parameter.isOptionalPositional) {
final matchingParameter = _matchingParameter(parameter,
superParameterType: parameter.type,
defaultName: '__p$position');
defaultName: '__p$position',
forceNullable: true);
b.optionalParameters.add(matchingParameter);
position++;
} else if (parameter.isOptionalNamed) {
final matchingParameter = _matchingParameter(parameter,
superParameterType: parameter.type);
superParameterType: parameter.type, forceNullable: true);
b.optionalParameters.add(matchingParameter);
} else if (parameter.isRequiredNamed) {
final matchingParameter = _matchingParameter(parameter,
Expand Down
4 changes: 2 additions & 2 deletions test/builder/auto_mocks_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2414,7 +2414,7 @@ void main() {
_containsAllOf('''
returnValue: (
int __p0, [
String __p1,
String? __p1,
]) {},'''),
);
});
Expand All @@ -2431,7 +2431,7 @@ void main() {
_containsAllOf('''
returnValue: (
_i2.Foo __p0, {
bool b,
bool? b,
}) {},'''),
);
});
Expand Down
3 changes: 3 additions & 0 deletions test/end2end/foo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class Foo<T> {
Future<void>? returnsNullableFutureVoid() => Future.value();
Future<T> returnsFuture(T x) => Future.value(x);
Bar returnsBar(int arg) => Bar();
String Function(int x, [String s]) returnsFunction() => (x, [s = '']) => '';
String Function(int x, {String s}) returnsFunctionNamed() =>
(x, {s = ''}) => '';
}

class Bar {
Expand Down
16 changes: 16 additions & 0 deletions test/end2end/generated_mocks_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,22 @@ void main() {
when(foo.returnsFuture(any)).thenAnswer((_) async => 1);
expect(await foo.returnsFuture(0), 1);
});

test(
'a method returning a function with optional non-nullable argument '
'can be stubbed', () {
when(foo.returnsFunction()).thenReturn((x, [s = 'x']) => s + s);
expect(foo.returnsFunction()(1), equals('xx'));
expect(foo.returnsFunction()(1, 'y'), equals('yy'));
});

test(
'a method returning a function with named optional non-nullable '
'argument can be stubbed', () {
when(foo.returnsFunctionNamed()).thenReturn((x, {s = 'x'}) => s + s);
expect(foo.returnsFunctionNamed()(1), equals('xx'));
expect(foo.returnsFunctionNamed()(1, s: 'y'), equals('yy'));
});
});

group('for a generated mock using unsupportedMembers', () {
Expand Down

0 comments on commit dc3eb65

Please sign in to comment.