Skip to content

Test fails due to generated mocks attemps to cast type 'Future<List<dynamic>>' to 'Future<Iterable<Weather>>' #380

@eriklange

Description

@eriklange

I'm mocking a method getWeather() which returns Future<Iterable<Weather>>()

It seems like the generated mock class' getWeather() creates a new Future<Iterable<dynamic>>, and then attempts to cast that directly to Future<Iterable<Weather>>, which does not work.

This results in the error

type 'Future<List<dynamic>>' is not a subtype of type 'Future<Iterable<Weather>>' in type cast
MockWeatherRepository.getWeather
test\…\weather\weather_bloc_test.mocks.dart:85
main.<fn>.<fn>.<fn>
test\…\weather\weather_bloc_test.dart:82
testBloc.<fn>
package:bloc_test/src/bloc_test.dart:160
testBloc.<fn>
package:bloc_test/src/bloc_test.dart:158
dart:async                                            runZonedGuarded
testBloc
package:bloc_test/src/bloc_test.dart:157
blocTest.<fn>
package:bloc_test/src/bloc_test.dart:129
blocTest.<fn>
package:bloc_test/src/bloc_test.dart:128
===== asynchronous gap ===========================
dart:async                                            _completeOnAsyncError
package:bloc_test/src/bloc_test.dart                  testBloc.<fn>
package:bloc_test/src/bloc_test.dart:1
testBloc.<fn>
package:bloc_test/src/bloc_test.dart:158
dart:async                                            runZonedGuarded

weather_bloc.test.dart:

@GenerateMocks([Weather, WeatherRepository])
main() {
  group('WeatherBloc', () {
    late WeatherRepository weatherRepository;
    late WeatherBloc weatherBloc;

    setUp(() {
      weatherRepository = MockWeatherRepository();
      weatherBloc = WeatherBloc(weatherRepository: weatherRepository);
    });

    tearDown(() {
      weatherBloc.close();
    });

    group('WeatherRefreshRequested', () {
      blocTest<WeatherBloc, WeatherState>(
        'Emits [WeatherLoadInProgress, WeatherLoadFailure] when weather repository throws error',
        build: () {
          when(weatherRepository.getWeather()).thenThrow('Weather Error');

          return weatherBloc;
        },
        act: (bloc) => bloc.add(WeatherRefreshRequested()),
        expect: () => [],
      );
    });
  });
}

MockWeatherRepository

class MockWeatherRepository extends _i1.Mock implements _i7.WeatherRepository {
  MockWeatherRepository() {
    _i1.throwOnMissingStub(this);
  }

  @override
  _i4.NasaApiClient get nasaApiClient =>
      (super.noSuchMethod(Invocation.getter(#nasaApiClient),
          returnValue: _FakeNasaApiClient()) as _i4.NasaApiClient);
  @override
  _i8.Future<Iterable<_i5.Weather>> getWeather() =>
      (super.noSuchMethod(Invocation.method(#getWeather, []),
          returnValue: Future.value([])) as _i8.Future<Iterable<_i5.Weather>>);
}

flutter doctor

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.0.4, on Microsoft Windows [Version 10.0.19041.867], locale en-GB)
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[√] Chrome - develop for the web
[√] Android Studio (version 4.1.0)
[√] IntelliJ IDEA Community Edition (version 2017.1)
[√] VS Code (version 1.55.0)
[√] Connected device (2 available)

• No issues found!

I did manage to fix the problem by specifying the type in the object that is attempted to be casted to Future<Iterable>

MockWeatherRepository Fix

@override
  _i8.Future<Iterable<_i5.Weather>> getWeather() =>
      (super.noSuchMethod(Invocation.method(#getWeather, []),
          returnValue: Future<Iterable<Weather>>.value([])) as _i8.Future<Iterable<_i5.Weather>>);

The fix is that instead of Future.value([]), I specified the type as Future<Iterable<Weather>>.value([]))

Am I using mockito wrong, or is this a bug?

Metadata

Metadata

Assignees

Labels

P2A bug or feature request we're likely to work ontype-bugIncorrect behavior (everything from a crash to more subtle misbehavior)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions