Matcher is not working properly is specific case due to Object?
Hi all,
thanks a lot for this great library, it saved me so much time with testing and made testing more enjoyable :P
I am facing the following issue: I am defining what a mock object specific function should perform with the when method but the function doesn't run. I assume the matcher doesn't consider the two functions equal.
I think it might be due to the GoRouter pushNamed extra parameter (the type is "Object?") but even adding the any(named: "extra") doesn't help. I tried without any, with any(named: "extra") and even any(named: "extra", that: isA<Object?>()) with no success.
To Reproduce Class
class ShowHcaptcha {
final GoRouter _router;
ShowHcaptcha(this._router);
Future<String> call() async {
String? hCaptchaToken =
await _router.pushNamed(HCaptchaDialog.routeName, extra: null);
if (hCaptchaToken == null) {
throw HcaptchaFailure();
} else {
return hCaptchaToken;
}
}
}
Test Failing
class MockGoRouter extends Mock implements GoRouter {}
void main() {
late MockGoRouter mockGoRouter;
late ShowHcaptcha showHcaptcha;
String captchaResult = "testResult";
setUp(() {
mockGoRouter = MockGoRouter();
showHcaptcha = ShowHcaptcha(mockGoRouter);
});
setUpAll(() {
registerFallbackValue(null);
});
test('should push to HCaptchaDialog & return the result on success',
() async {
//assign
when(
() => mockGoRouter.pushNamed(HCaptchaDialog.routeName,
extra: any(named: "extra", that: isA<Object?>())),
).thenAnswer((invocation) async => captchaResult);
//act
final result = await showHcaptcha();
//assert
expect(result, captchaResult);
verify(
() => mockGoRouter.pushNamed(HCaptchaDialog.routeName),
).called(1);
verifyNoMoreInteractions(mockGoRouter);
});
}
On another usecase I used the Mocktail when function for a similar case and it worked fine. Successful test:
when(
() => mockRouter.pushNamed(any(), extra: newEmailUser.email),
).thenAnswer((invocation) async {
return null;
});
Error thrown by failing test:
type 'Null' is not a subtype of type 'Future<String?>'
test/features/auth/domain/usecases/show_hcaptcha_test.dart 7:7 MockGoRouter.pushNamed
package:athlas/features/auth/domain/usecases/show_hcaptcha.dart 17:23 ShowHcaptcha.call
test/features/auth/domain/usecases/show_hcaptcha_test.dart 32:38 main.
Solved it, what was causing the issue was this line in the class code
String? hCaptchaToken =
await _router.pushNamed(HCaptchaDialog.routeName);
Working solution is:
final hCaptchaToken =
await _router.pushNamed(HCaptchaDialog.routeName);
Does anyone know why defining the return value type causes such issue? Thanks
I'm guessing it's because of the generic type not matching. Glad you figured it out!