Search code examples
flutterscreen-orientationflutter-test

How to test the preferred screen orientation


I'm working with a (simplified) widget that sets the screen orientation to "landscape" when initiated and resets it to "portrait" when disposed:

class LandScapeWidget extends StatefulWidget {
  const LandScapeWidget({Key? key}) : super(key: key);

  @override
  State<LandScapeWidget> createState() => _LandScapeWidgetState();
}

class _LandScapeWidgetState extends State<LandScapeWidget> {
  @override
  void initState() {
    super.initState();
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeLeft,
    ]);
  }

  @override
  void dispose() {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return const SizedBox.shrink();
  }
}

How can I write a test on this behavior?


Solution

  • I got the inspiration from this flutter test.

    void main() {
     testWidgets('It should be in the landscape view', (tester) async {
        const widget = LandScapeWidget();
    
        final logs = [];
    
        tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (methodCall) async {
          if (methodCall.method == 'SystemChrome.setPreferredOrientations') {
            logs.add((methodCall.arguments as List)[0]);
          }
          return null;
        });
    
        expect(logs.length, 0);
    
        await tester.pumpWidget(
          const MaterialApp(
            home: widget,
          ),
        );
    
        expect(logs.length, 1, reason: 'It should have pushed a log after the initState');
        expect(logs.first, 'DeviceOrientation.landscapeLeft', reason: 'It should be in the landscape view after the initState');
    
        await tester.pumpWidget(const SizedBox()); // Disposes the widget
        expect(logs.length, 2, reason: 'It should have added a log after the dispose');
        expect(logs.last, 'DeviceOrientation.portraitUp', reason: 'It should be in the landscape view after the dispose');
      });