I am in the process of implementing a widget test for a login screen. In the app, the login screen offers the user a switch control to set preferences for biometrics if they are available on the device.
We are researching GetX and need to test this behavior in a widget test. The login screen is a stateless widget that loads a GetXController
subclass called LoginViewController
as a dependency. This controller class contains an observable boolean called canCheckBiometrics
, has a setter called setBiometrics(bool newValue)
and is used to determine the presence of the switch control. The LoginView stateless widget checks for the presence of biometrics using local_auth
package and calls setBiometrics accordingly. Code excerpt from LoginView:
final controller = Get.put(LoginViewController());
Future<void> _checkForBiometrics() async {
bool enabled = await localAuth.canCheckBiometrics;
controller.setBiometrics(enabled);
}
What I would like to do is mock the LoginViewController
class in my widget test and call the setBiometrics
as needed to perform tests. Below is a section of my widget test:
class MockLoginViewController extends Mock implements LoginViewController {}
void main(){
final controller = MockLoginViewController();
setUp(() { });
tearDown(() { });
group('Controls are present and functioning', () {
// ... other tests
testWidgets('Biometrics switcher present conditionally', (tester) async {
await tester.pumpWidget(const _LoginWrapper());
var biometricsSwitch = find.byKey(UIKeys.keySwitchBiometrics);
// if controller.canCheckBiometrics.value is true
// controller.setBiometrics(true);
// expect(biometricsSwitch, findsOneWidget);
// if controller.canCheckBiometrics.value is false
// controller.setBiometrics(false);
// expect(biometricsSwitch, findsNothing);
});
class _LoginWrapper extends StatelessWidget {
const _LoginWrapper({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(home: LoginView());
}
}
The LoginView
has to be wrapped in a MaterialApp
to avoid MediaQuery
errors.
My question is: how can I associate the MockLoginViewController
class with the widget being tested so that I can toggle the value and test the presence of the switcher? Or am I going about this all wrong?
NOTE: I attempted to try the get_test
package to help with this, but it does not support null safety, and is therefore useless.