diff --git a/CHANGELOG.md b/CHANGELOG.md index eb338ee0..42496d5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ * Require analyzer 5.2.0. * Fix nice mocks generation in mixed mode (generated code is pre null-safety, while mocked class is null-safe). -* Require Dart >= 2.18.0. +* Require Dart >= 2.17.0. * Support typedef-aliased classes in `@GenerateMocks` and `@GenerateNiceMocks` ## 5.3.2 diff --git a/analysis_options.yaml b/analysis_options.yaml index 860c620e..0cfb93b3 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,4 +1,5 @@ include: package:lints/recommended.yaml + analyzer: language: strict-casts: true @@ -7,4 +8,4 @@ linter: rules: - comment_references - test_types_in_equals - - throw_in_finally + - throw_in_finally \ No newline at end of file diff --git a/lib/src/builder.dart b/lib/src/builder.dart index 7ee303f2..71bbeb52 100644 --- a/lib/src/builder.dart +++ b/lib/src/builder.dart @@ -618,6 +618,11 @@ class _MockTargetGatherer { } final mixinInterfaceType = _determineDartType(typeToMixin, entryLib.typeProvider); + if (!mixinInterfaceType.interfaces.contains(type)) { + throw InvalidMockitoAnnotationException('The "mixingIn" type, ' + '${typeToMixin.getDisplayString(withNullability: false)}, must ' + 'implement the class to mock, ${typeToMock.getDisplayString(withNullability: false)}'); + } mixins.add(mixinInterfaceType); } diff --git a/test/builder/custom_mocks_test.dart b/test/builder/custom_mocks_test.dart index 81999230..71dc963f 100644 --- a/test/builder/custom_mocks_test.dart +++ b/test/builder/custom_mocks_test.dart @@ -415,29 +415,6 @@ void main() { ); }); - test('generates a mock class with a marker mixin', () async { - var mocksContent = await buildWithNonNullable({ - ...annotationsAsset, - 'foo|lib/foo.dart': ''' - class Foo {} - class FooMarkerMixin {} - ''', - 'foo|test/foo_test.dart': ''' - import 'package:foo/foo.dart'; - import 'package:mockito/annotations.dart'; - @GenerateMocks([], customMocks: [ - MockSpec(mixingIn: [FooMarkerMixin]) - ]) - void main() {} - ''' - }); - expect( - mocksContent, - contains( - 'class MockFoo extends _i1.Mock with _i2.FooMarkerMixin implements _i2.Foo {'), - ); - }); - test( 'generates a mock class which uses the old behavior of returning null on ' 'missing stubs', () async { @@ -1238,6 +1215,27 @@ void main() { ); }); + test('throws when MockSpec mixes in a non-mixinable type', () async { + _expectBuilderThrows( + assets: { + ...annotationsAsset, + 'foo|lib/foo.dart': dedent(''' + class Foo {} + '''), + 'foo|test/foo_test.dart': dedent(''' + import 'package:mockito/annotations.dart'; + import 'package:foo/foo.dart'; + @GenerateMocks([], customMocks: [MockSpec(mixingIn: [FooMixin])]) + void main() {} + + mixin FooMixin {} + '''), + }, + message: contains( + 'The "mixingIn" type, FooMixin, must implement the class to mock, Foo'), + ); + }); + test('throws when type argument is unknown type', () async { _expectBuilderThrows( assets: {