Accessing GetXController in a Flutter widget test

1.6k views Asked by At

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.

0

There are 0 answers