There are similar issues asking about the same error (e.g. here), but their cause was due to improper mocking. In my case, I seem to have the method properly mocked, yet when I debug in Visual Studio Code with All Exceptions enabled, then I get the runtime exception:
_TypeError (type 'Null' is not a subtype of type 'Future<AuthenticationToken?>')
If I continue the test past the exception (or simply debug the tests with All Exceptions disabled or simply run them without debugging), all my tests pass ok.
dependencies:
hive: ^2.0.4
hive_flutter: ^1.1.0
dev_dependencies:
mocktail: ^0.1.4
import 'package:hive/hive.dart';
class AuthenticationRepository {
static const _currentTokenKey = 'key';
AuthenticationToken? _inMemoryToken;
Future<Box<AuthenticationToken?>> _tokenBox;
...
Future<AuthenticationToken?> activeToken() async =>
_inMemoryToken ?? (await _tokenBox).get(_currentTokenKey);
...
}
Sample test file:
import 'package:app/src/data/authentication/repository.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
class MockAuthenticationRepository extends Mock
implements AuthenticationRepository {}
void main() {
AuthenticationRepository authenticationRepository;
SUT sut; // SUT depends on AuthenticationRepository
setUp(() {
authenticationRepository = MockAuthenticationRepository();
when(() => authenticationRepository.activeToken())
.thenAnswer((realInvocation) => Future.value(AuthenticationToken()));
sut = SUT(authenticationRepository);
});
test('some test', () async {
await sut.someMethod();
verify(() => authenticationRepository.activeToken()).called(1);
});
}
Here is the stack trace:
MockAuthenticationRepository.activeToken (/Users/davilin/Documents/Projects/app/flutter/app/lib/src/data/authentication/repository.dart:296)
main.initMocks.<anonymous closure> (/Users/davilin/Documents/Projects/app/flutter/app/test/network/token_refresh_interceptor_test.dart:33)
when.<anonymous closure> (/Users/davilin/.pub-cache/hosted/pub.dartlang.org/mocktail-0.1.4/lib/src/mocktail.dart:211)
main.initMocks (/Users/davilin/Documents/Projects/app/flutter/app/test/network/token_refresh_interceptor_test.dart:33)
main.<anonymous closure>.<anonymous closure> (/Users/davilin/Documents/Projects/app/flutter/app/test/network/token_refresh_interceptor_test.dart:52)
Declarer._runSetUps.<anonymous closure> (/Users/davilin/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.2/lib/src/backend/declarer.dart:329)
Future.forEach.<anonymous closure> (dart:async/future.dart:495)
Future.doWhile.<anonymous closure> (dart:async/future.dart:535)
StackZoneSpecification._registerUnaryCallback.<anonymous closure>.<anonymous closure> (/Users/davilin/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/src/stack_zone_specification.dart:126)
StackZoneSpecification._run (/Users/davilin/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/src/stack_zone_specification.dart:208)
StackZoneSpecification._registerUnaryCallback.<anonymous closure> (/Users/davilin/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/src/stack_zone_specification.dart:126)
_rootRunUnary (dart:async/zone.dart:1436)
_CustomZone.runUnary (dart:async/zone.dart:1335)
_CustomZone.runUnaryGuarded (dart:async/zone.dart:1244)
_CustomZone.bindUnaryCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1281)
Future.doWhile (dart:async/future.dart:551)
Future.forEach (dart:async/future.dart:493)
Declarer._runSetUps (/Users/davilin/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.2/lib/src/backend/declarer.dart:329)
<asynchronous gap> (Unknown Source:0)
StackZoneSpecification._registerUnaryCallback.<anonymous closure> (/Users/davilin/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/src/stack_zone_specification.dart:0)
<asynchronous gap> (Unknown Source:0)
I just wanted to document this, in case someone can offer an explanation why this happens.
