MockBuilder: Widen the type of non-nullable parameters to be nullable.

The mechanism for doing this is to add some `forceNullable` parameters here and there, to ensure that overriding method parameters and overriding setter parameters are nullable. Other parameters, like those of function-typed parameters or generic function types, are not widened.

Include plenty of tests, and update all test expectations to now include widened parameters.

Update a few tests as well to be simpler, including only relevant content, and testing only relevant content.

PiperOrigin-RevId: 315296150
diff --git a/lib/src/builder.dart b/lib/src/builder.dart
index c637462..a543527 100644
--- a/lib/src/builder.dart
+++ b/lib/src/builder.dart
@@ -222,10 +222,8 @@
   ///
   /// This new method just calls `super.noSuchMethod`, optionally passing a
   /// return value for methods with a non-nullable return type.
-  // TODO(srawlins): This method does no widening yet. Widen parameters. Include
-  // tests for typedefs, old-style function parameters, function types, type
-  // variables, non-nullable type variables (bounded to Object, I think),
-  // dynamic.
+  // TODO(srawlins): Include widening tests for typedefs, old-style function
+  // parameters, function types.
   void _buildOverridingMethod(MethodBuilder builder, MethodElement method) {
     // TODO(srawlins): generator methods like async*, sync*.
     var name = method.displayName;
@@ -252,13 +250,16 @@
 
     for (final parameter in method.parameters) {
       if (parameter.isRequiredPositional) {
-        builder.requiredParameters.add(_matchingParameter(parameter));
+        builder.requiredParameters
+            .add(_matchingParameter(parameter, forceNullable: true));
         invocationPositionalArgs.add(refer(parameter.displayName));
       } else if (parameter.isOptionalPositional) {
-        builder.optionalParameters.add(_matchingParameter(parameter));
+        builder.optionalParameters
+            .add(_matchingParameter(parameter, forceNullable: true));
         invocationPositionalArgs.add(refer(parameter.displayName));
       } else if (parameter.isNamed) {
-        builder.optionalParameters.add(_matchingParameter(parameter));
+        builder.optionalParameters
+            .add(_matchingParameter(parameter, forceNullable: true));
         invocationNamedArgs[refer('#${parameter.displayName}')] =
             refer(parameter.displayName);
       }
@@ -377,13 +378,19 @@
   }
 
   /// Returns a [Parameter] which matches [parameter].
+  ///
+  /// If [parameter] is unnamed (like a positional parameter in a function
+  /// type), a [defaultName] can be passed as the name.
+  ///
+  /// If the type needs to be nullable, rather than matching the nullability of
+  /// [parameter], use [forceNullable].
   Parameter _matchingParameter(ParameterElement parameter,
-      {String defaultName}) {
+      {String defaultName, bool forceNullable = false}) {
     var name = parameter.name?.isEmpty ?? false ? defaultName : parameter.name;
     return Parameter((pBuilder) {
       pBuilder
         ..name = name
-        ..type = _typeReference(parameter.type);
+        ..type = _typeReference(parameter.type, forceNullable: forceNullable);
       if (parameter.isNamed) pBuilder.named = true;
       if (parameter.defaultValueCode != null) {
         pBuilder.defaultTo = Code(parameter.defaultValueCode);
@@ -416,7 +423,6 @@
   /// type to be nullable if it is non-nullable.
   ///
   /// This new setter just calls `super.noSuchMethod`.
-  // TODO(srawlins): This method does no widening yet.
   void _buildOverridingSetter(
       MethodBuilder builder, PropertyAccessorElement setter) {
     builder
@@ -430,7 +436,7 @@
       if (parameter.isRequiredPositional) {
         builder.requiredParameters.add(Parameter((pBuilder) => pBuilder
           ..name = parameter.displayName
-          ..type = _typeReference(parameter.type)));
+          ..type = _typeReference(parameter.type, forceNullable: true)));
         invocationPositionalArgs.add(refer(parameter.displayName));
       }
     }
@@ -458,6 +464,9 @@
 
   /// Create a reference for [type], properly referencing all attached types.
   ///
+  /// If the type needs to be nullable, rather than matching the nullability of
+  /// [type], use [forceNullable].
+  ///
   /// This creates proper references for:
   /// * InterfaceTypes (classes, generic classes),
   /// * FunctionType parameters (like `void callback(int i)`),
@@ -466,12 +475,13 @@
   /// * type variables.
   // TODO(srawlins): Contribute this back to a common location, like
   // package:source_gen?
-  Reference _typeReference(analyzer.DartType type) {
+  Reference _typeReference(analyzer.DartType type,
+      {bool forceNullable = false}) {
     if (type is analyzer.InterfaceType) {
       return TypeReference((b) {
         b
           ..symbol = type.name
-          ..isNullable = typeSystem.isPotentiallyNullable(type)
+          ..isNullable = forceNullable || typeSystem.isPotentiallyNullable(type)
           ..url = _typeImport(type)
           ..types.addAll(type.typeArguments.map(_typeReference));
       });
@@ -481,6 +491,7 @@
         // [type] represents a FunctionTypedFormalParameter.
         return FunctionType((b) {
           b
+            // TODO(srawlins): Fix FunctionType to take an `isNullable` value.
             ..returnType = _typeReference(type.returnType)
             ..requiredParameters
                 .addAll(type.normalParameterTypes.map(_typeReference))
@@ -495,7 +506,8 @@
         var typedef = element.enclosingElement;
         b
           ..symbol = typedef.name
-          ..url = _typeImport(type);
+          ..url = _typeImport(type)
+          ..isNullable = forceNullable || typeSystem.isNullable(type);
         for (var typeArgument in type.typeArguments) {
           b.types.add(_typeReference(typeArgument));
         }
@@ -504,7 +516,7 @@
       return TypeReference((b) {
         b
           ..symbol = type.name
-          ..isNullable = typeSystem.isNullable(type);
+          ..isNullable = forceNullable || typeSystem.isNullable(type);
       });
     } else {
       return refer(type.displayName, _typeImport(type));
diff --git a/test/builder_test.dart b/test/builder_test.dart
index fb550e8..11273ee 100644
--- a/test/builder_test.dart
+++ b/test/builder_test.dart
@@ -83,9 +83,7 @@
         extension X on Foo {
           dynamic x(int m, String n) => n + 1;
         }
-        class Foo {
-          dynamic a(int m, String n) => n + 1;
-        }
+        class Foo {}
         '''),
       },
       outputs: {
@@ -96,10 +94,7 @@
         /// A class which mocks [Foo].
         ///
         /// See the documentation for Mockito's code generation for more information.
-        class MockFoo extends _i1.Mock implements _i2.Foo {
-          dynamic a(int m, String n) =>
-              super.noSuchMethod(Invocation.method(#a, [m, n]));
-        }
+        class MockFoo extends _i1.Mock implements _i2.Foo {}
         '''),
       },
     );
@@ -134,15 +129,15 @@
         ///
         /// See the documentation for Mockito's code generation for more information.
         class MockFoo extends _i1.Mock implements _i2.Foo {
-          dynamic a(int m, String n) =>
+          dynamic a(int? m, String? n) =>
               super.noSuchMethod(Invocation.method(#a, [m, n]));
-          dynamic b(List<int> list) =>
+          dynamic b(List<int>? list) =>
               super.noSuchMethod(Invocation.method(#b, [list]));
-          void c(String one, [String two, String three = ""]) =>
+          void c(String? one, [String? two, String? three = ""]) =>
               super.noSuchMethod(Invocation.method(#c, [one, two, three]));
-          void d(String one, {String two, String three = ""}) => super
+          void d(String? one, {String? two, String? three = ""}) => super
               .noSuchMethod(Invocation.method(#d, [one], {#two: two, #three: three}));
-          _i3.Future<void> e(String s) async =>
+          _i3.Future<void> e(String? s) async =>
               super.noSuchMethod(Invocation.method(#e, [s]), Future.value(null));
         }
         '''),
@@ -155,12 +150,8 @@
       {
         ...annotationsAsset,
         'foo|lib/foo.dart': dedent(r'''
-        class Foo {
-          dynamic a(int m, String n) => n + 1;
-        }
-        class Bar {
-          dynamic b(List<int> list) => list.length;
-        }
+        class Foo {}
+        class Bar {}
         '''),
         'foo|test/foo_test.dart': '''
         import 'package:foo/foo.dart';
@@ -170,26 +161,10 @@
         '''
       },
       outputs: {
-        'foo|test/foo_test.mocks.dart': dedent(r'''
-        import 'package:mockito/mockito.dart' as _i1;
-        import 'package:foo/foo.dart' as _i2;
-
-        /// A class which mocks [Foo].
-        ///
-        /// See the documentation for Mockito's code generation for more information.
-        class MockFoo extends _i1.Mock implements _i2.Foo {
-          dynamic a(int m, String n) =>
-              super.noSuchMethod(Invocation.method(#a, [m, n]));
-        }
-
-        /// A class which mocks [Bar].
-        ///
-        /// See the documentation for Mockito's code generation for more information.
-        class MockBar extends _i1.Mock implements _i2.Bar {
-          dynamic b(List<int> list) =>
-              super.noSuchMethod(Invocation.method(#b, [list]));
-        }
-        '''),
+        'foo|test/foo_test.mocks.dart': _containsAllOf(
+          'class MockFoo extends _i1.Mock implements _i2.Foo {}',
+          'class MockBar extends _i1.Mock implements _i2.Bar {}',
+        ),
       },
     );
   });
@@ -199,9 +174,7 @@
       {
         ...annotationsAsset,
         'foo|lib/foo.dart': dedent(r'''
-        class Foo<T, U> {
-          dynamic a(int m) => m + 1;
-        }
+        class Foo<T, U> {}
         '''),
         'foo|test/foo_test.dart': '''
         import 'package:foo/foo.dart';
@@ -211,17 +184,8 @@
         '''
       },
       outputs: {
-        'foo|test/foo_test.mocks.dart': dedent(r'''
-        import 'package:mockito/mockito.dart' as _i1;
-        import 'package:foo/foo.dart' as _i2;
-
-        /// A class which mocks [Foo].
-        ///
-        /// See the documentation for Mockito's code generation for more information.
-        class MockFoo<T, U> extends _i1.Mock implements _i2.Foo<T, U> {
-          dynamic a(int m) => super.noSuchMethod(Invocation.method(#a, [m]));
-        }
-        '''),
+        'foo|test/foo_test.mocks.dart': _containsAllOf(
+            'class MockFoo<T, U> extends _i1.Mock implements _i2.Foo<T, U> {}'),
       },
     );
   });
@@ -231,12 +195,8 @@
       {
         ...annotationsAsset,
         'foo|lib/foo.dart': dedent(r'''
-        class Foo {
-          dynamic a(int m) => m + 1;
-        }
-        class Bar<T extends Foo> {
-          dynamic b(int m) => m + 1;
-        }
+        class Foo {}
+        class Bar<T extends Foo> {}
         '''),
         'foo|test/foo_test.dart': '''
         import 'package:foo/foo.dart';
@@ -246,24 +206,10 @@
         '''
       },
       outputs: {
-        'foo|test/foo_test.mocks.dart': dedent(r'''
-        import 'package:mockito/mockito.dart' as _i1;
-        import 'package:foo/foo.dart' as _i2;
-
-        /// A class which mocks [Foo].
-        ///
-        /// See the documentation for Mockito's code generation for more information.
-        class MockFoo extends _i1.Mock implements _i2.Foo {
-          dynamic a(int m) => super.noSuchMethod(Invocation.method(#a, [m]));
-        }
-
-        /// A class which mocks [Bar].
-        ///
-        /// See the documentation for Mockito's code generation for more information.
-        class MockBar<T extends _i2.Foo> extends _i1.Mock implements _i2.Bar<T> {
-          dynamic b(int m) => super.noSuchMethod(Invocation.method(#b, [m]));
-        }
-        '''),
+        'foo|test/foo_test.mocks.dart': _containsAllOf(
+          'class MockFoo extends _i1.Mock implements _i2.Foo {}',
+          'class MockBar<T extends _i2.Foo> extends _i1.Mock implements _i2.Bar<T> {}',
+        ),
       },
     );
   });
@@ -290,9 +236,10 @@
         ///
         /// See the documentation for Mockito's code generation for more information.
         class MockFoo<T> extends _i1.Mock implements _i2.Foo<T> {
-          void f(dynamic a, int b) => super.noSuchMethod(Invocation.method(#f, [a, b]));
-          void g(T c) => super.noSuchMethod(Invocation.method(#g, [c]));
-          void h<U>(U d) => super.noSuchMethod(Invocation.method(#h, [d]));
+          void f(dynamic a, int? b) =>
+              super.noSuchMethod(Invocation.method(#f, [a, b]));
+          void g(T? c) => super.noSuchMethod(Invocation.method(#g, [c]));
+          void h<U>(U? d) => super.noSuchMethod(Invocation.method(#h, [d]));
         }
         '''),
       },
@@ -320,7 +267,7 @@
         ///
         /// See the documentation for Mockito's code generation for more information.
         class MockFoo extends _i1.Mock implements _i2.Foo {
-          dynamic f(List<_i2.Foo> list) =>
+          dynamic f(List<_i2.Foo>? list) =>
               super.noSuchMethod(Invocation.method(#f, [list]));
         }
         '''),
@@ -354,9 +301,9 @@
         ///
         /// See the documentation for Mockito's code generation for more information.
         class MockFoo extends _i1.Mock implements _i2.Foo {
-          dynamic f(_i2.Callback c) => super.noSuchMethod(Invocation.method(#f, [c]));
-          dynamic g(_i2.Callback2 c) => super.noSuchMethod(Invocation.method(#g, [c]));
-          dynamic h(_i2.Callback3<_i2.Foo> c) =>
+          dynamic f(_i2.Callback? c) => super.noSuchMethod(Invocation.method(#f, [c]));
+          dynamic g(_i2.Callback2? c) => super.noSuchMethod(Invocation.method(#g, [c]));
+          dynamic h(_i2.Callback3<_i2.Foo>? c) =>
               super.noSuchMethod(Invocation.method(#h, [c]));
         }
         '''),
@@ -408,53 +355,132 @@
     );
   });
 
-  test('correctly matches nullability of parameters', () async {
-    await _testWithNonNullable(
-      {
-        ...annotationsAsset,
-        ...simpleTestAsset,
-        'foo|lib/foo.dart': dedent(r'''
+  test('widens the type of parameters to be nullable', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
         abstract class Foo {
-          void f(int? a, int b);
-          void g(List<int?> a, List<int> b);
-          void h(int? Function() a, int Function() b);
-          void i(void Function(int?) a, void Function(int) b);
-          void j(int? a(), int b());
-          void k(void a(int? x), void b(int x));
-          void l<T>(T? a, T b);
-          void m(dynamic a, int b);
+          void m(int? a, int b);
         }
         '''),
-      },
-      outputs: {
-        'foo|test/foo_test.mocks.dart': dedent(r'''
-        import 'package:mockito/mockito.dart' as _i1;
-        import 'package:foo/foo.dart' as _i2;
-
-        /// A class which mocks [Foo].
-        ///
-        /// See the documentation for Mockito's code generation for more information.
-        class MockFoo extends _i1.Mock implements _i2.Foo {
-          void f(int? a, int b) => super.noSuchMethod(Invocation.method(#f, [a, b]));
-          void g(List<int?> a, List<int> b) =>
-              super.noSuchMethod(Invocation.method(#g, [a, b]));
-          void h(int? Function() a, int Function() b) =>
-              super.noSuchMethod(Invocation.method(#h, [a, b]));
-          void i(void Function(int?) a, void Function(int) b) =>
-              super.noSuchMethod(Invocation.method(#i, [a, b]));
-          void j(int? Function() a, int Function() b) =>
-              super.noSuchMethod(Invocation.method(#j, [a, b]));
-          void k(void Function(int?) a, void Function(int) b) =>
-              super.noSuchMethod(Invocation.method(#k, [a, b]));
-          void l<T>(T? a, T b) => super.noSuchMethod(Invocation.method(#l, [a, b]));
-          void m(dynamic a, int b) => super.noSuchMethod(Invocation.method(#m, [a, b]));
-        }
-        '''),
-      },
+      _containsAllOf(
+          'void m(int? a, int? b) => super.noSuchMethod(Invocation.method(#m, [a, b]));'),
     );
   });
 
-  test('correctly matches nullability of return types', () async {
+  test(
+      'widens the type of potentially non-nullable type variables to be '
+      'nullable', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+        abstract class Foo<T> {
+          void m(int? a, T b);
+        }
+        '''),
+      _containsAllOf(
+          'void m(int? a, T? b) => super.noSuchMethod(Invocation.method(#m, [a, b]));'),
+    );
+  });
+
+  test('matches nullability of type arguments of a parameter', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+        abstract class Foo {
+          void m(List<int?> a, List<int> b);
+        }
+        '''),
+      _containsAllOf('void m(List<int?>? a, List<int>? b) =>',
+          'super.noSuchMethod(Invocation.method(#m, [a, b]));'),
+    );
+  });
+
+  test(
+      'matches nullability of return type of a generic function-typed '
+      'parameter', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+        abstract class Foo {
+          void m(int? Function() a, int Function() b);
+        }
+        '''),
+      // `a` and `b` should be nullable. code_builder needs a fix, allowing a
+      // FunctionTypeBuilder to take an `isNullable` value.
+      _containsAllOf('void m(int? Function() a, int Function() b) =>',
+          'super.noSuchMethod(Invocation.method(#m, [a, b]));'),
+    );
+  });
+
+  test(
+      'matches nullability of parameter types within a generic function-typed '
+      'parameter', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+        abstract class Foo {
+          void m(void Function(int?) a, void Function(int) b);
+        }
+        '''),
+      // `a` and `b` should be nullable. code_builder needs a fix, allowing a
+      // FunctionTypeBuilder to take an `isNullable` value.
+      _containsAllOf('void m(void Function(int?) a, void Function(int) b) =>',
+          'super.noSuchMethod(Invocation.method(#m, [a, b]));'),
+    );
+  });
+
+  test('matches nullability of return type of a function-typed parameter',
+      () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+        abstract class Foo {
+          void m(int? a(), int b());
+        }
+        '''),
+      // `a` and `b` should be nullable. code_builder needs a fix, allowing a
+      // FunctionTypeBuilder to take an `isNullable` value.
+      _containsAllOf('void m(int? Function() a, int Function() b) =>',
+          'super.noSuchMethod(Invocation.method(#m, [a, b]));'),
+    );
+  });
+
+  test(
+      'matches nullability of parameter types within a function-typed '
+      'parameter', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+        abstract class Foo {
+          void m(void a(int? x), void b(int x));
+        }
+        '''),
+      // `a` and `b` should be nullable. code_builder needs a fix, allowing a
+      // FunctionTypeBuilder to take an `isNullable` value.
+      _containsAllOf('void m(void Function(int?) a, void Function(int) b) =>',
+          'super.noSuchMethod(Invocation.method(#m, [a, b]));'),
+    );
+  });
+
+  test('matches nullability of a generic parameter', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+        abstract class Foo {
+          void m<T>(T? a, T b);
+        }
+        '''),
+      _containsAllOf(
+          'void m<T>(T? a, T? b) => super.noSuchMethod(Invocation.method(#m, [a, b]));'),
+    );
+  });
+
+  test('matches nullability of a dynamic parameter', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+        abstract class Foo {
+          void m(dynamic a, int b);
+        }
+        '''),
+      _containsAllOf('void m(dynamic a, int? b) =>',
+          'super.noSuchMethod(Invocation.method(#m, [a, b]));'),
+    );
+  });
+
+  test('matches nullability of return types', () async {
     await _testWithNonNullable(
       {
         ...annotationsAsset,
@@ -479,12 +505,12 @@
         ///
         /// See the documentation for Mockito's code generation for more information.
         class MockFoo extends _i1.Mock implements _i2.Foo {
-          int f(int a) => super.noSuchMethod(Invocation.method(#f, [a]), 0);
-          int? g(int a) => super.noSuchMethod(Invocation.method(#g, [a]));
-          List<int?> h(int a) => super.noSuchMethod(Invocation.method(#h, [a]), []);
-          List<int> i(int a) => super.noSuchMethod(Invocation.method(#i, [a]), []);
-          dynamic j(int a) => super.noSuchMethod(Invocation.method(#j, [a]));
-          T? k<T extends int>(int a) => super.noSuchMethod(Invocation.method(#k, [a]));
+          int f(int? a) => super.noSuchMethod(Invocation.method(#f, [a]), 0);
+          int? g(int? a) => super.noSuchMethod(Invocation.method(#g, [a]));
+          List<int?> h(int? a) => super.noSuchMethod(Invocation.method(#h, [a]), []);
+          List<int> i(int? a) => super.noSuchMethod(Invocation.method(#i, [a]), []);
+          dynamic j(int? a) => super.noSuchMethod(Invocation.method(#j, [a]));
+          T? k<T extends int>(int? a) => super.noSuchMethod(Invocation.method(#k, [a]));
         }
         '''),
       },
@@ -492,30 +518,14 @@
   });
 
   test('overrides abstract methods', () async {
-    await _testWithNonNullable(
-      {
-        ...annotationsAsset,
-        ...simpleTestAsset,
-        'foo|lib/foo.dart': dedent(r'''
-        abstract class Foo {
-          dynamic f(int a);
-          dynamic _g(int a);
-        }
-        '''),
-      },
-      outputs: {
-        'foo|test/foo_test.mocks.dart': dedent(r'''
-        import 'package:mockito/mockito.dart' as _i1;
-        import 'package:foo/foo.dart' as _i2;
-
-        /// A class which mocks [Foo].
-        ///
-        /// See the documentation for Mockito's code generation for more information.
-        class MockFoo extends _i1.Mock implements _i2.Foo {
-          dynamic f(int a) => super.noSuchMethod(Invocation.method(#f, [a]));
-        }
-        '''),
-      },
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+      abstract class Foo {
+        dynamic f(int a);
+      }
+      '''),
+      _containsAllOf(
+          'dynamic f(int? a) => super.noSuchMethod(Invocation.method(#f, [a]));'),
     );
   });
 
@@ -597,7 +607,7 @@
         ///
         /// See the documentation for Mockito's code generation for more information.
         class MockFoo<T> extends _i1.Mock implements _i2.Foo<T> {
-          void a(T m) => super.noSuchMethod(Invocation.method(#a, [m]));
+          void a(T? m) => super.noSuchMethod(Invocation.method(#a, [m]));
         }
         '''),
       },
@@ -627,8 +637,8 @@
         ///
         /// See the documentation for Mockito's code generation for more information.
         class MockFoo extends _i1.Mock implements _i2.Foo {
-          dynamic f<T>(int a) => super.noSuchMethod(Invocation.method(#f, [a]));
-          dynamic g<T extends _i2.Foo>(int a) =>
+          dynamic f<T>(int? a) => super.noSuchMethod(Invocation.method(#f, [a]));
+          dynamic g<T extends _i2.Foo>(int? a) =>
               super.noSuchMethod(Invocation.method(#g, [a]));
         }
         '''),
@@ -667,7 +677,7 @@
       }
       '''),
       _containsAllOf(
-          'set m(int a) => super.noSuchMethod(Invocation.setter(#m, [a]));'),
+          'set m(int? a) => super.noSuchMethod(Invocation.setter(#m, [a]));'),
     );
   });
 
@@ -691,7 +701,7 @@
       '''),
       _containsAllOf(
           'int get m => super.noSuchMethod(Invocation.getter(#m), 0);',
-          'set m(int _m) => super.noSuchMethod(Invocation.setter(#m, [_m]));'),
+          'set m(int? _m) => super.noSuchMethod(Invocation.setter(#m, [_m]));'),
     );
   });
 
@@ -741,35 +751,39 @@
     );
   });
 
-  test('overrides operators', () async {
-    await _testWithNonNullable(
-      {
-        ...annotationsAsset,
-        ...simpleTestAsset,
-        'foo|lib/foo.dart': dedent(r'''
-        class Foo {
-          int _b;
-          int operator +(Foo other) => _b + other._b;
-          bool operator ==(Object other) => other is Foo && _b == other._b;
-        }
-        '''),
-      },
-      outputs: {
-        'foo|test/foo_test.mocks.dart': dedent(r'''
-        import 'package:mockito/mockito.dart' as _i1;
-        import 'package:foo/foo.dart' as _i2;
+  test('overrides binary operators', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+      class Foo {
+        int operator +(Foo other) => 7;
+      }
+      '''),
+      _containsAllOf('int operator +(_i2.Foo? other) =>',
+          'super.noSuchMethod(Invocation.method(#+, [other]), 0);'),
+    );
+  });
 
-        /// A class which mocks [Foo].
-        ///
-        /// See the documentation for Mockito's code generation for more information.
-        class MockFoo extends _i1.Mock implements _i2.Foo {
-          int operator +(_i2.Foo other) =>
-              super.noSuchMethod(Invocation.method(#+, [other]), 0);
-          bool operator ==(Object other) =>
-              super.noSuchMethod(Invocation.method(#==, [other]), false);
-        }
-        '''),
-      },
+  test('overrides index operators', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+      class Foo {
+        int operator [](int x) => 7;
+      }
+      '''),
+      _containsAllOf(
+          'int operator [](int? x) => super.noSuchMethod(Invocation.method(#[], [x]), 0);'),
+    );
+  });
+
+  test('overrides unary operators', () async {
+    await _expectSingleNonNullableOutput(
+      dedent(r'''
+      class Foo {
+        int operator ~() => 7;
+      }
+      '''),
+      _containsAllOf(
+          'int operator ~() => super.noSuchMethod(Invocation.method(#~, []), 0);'),
     );
   });