flutterdartmockitowidget-test-flutter

Flutter widget test Clipboard.setData future then never triggered


I am trying to test a clipboard function in my app. When I press a button it should copy my text to the clipboard. When I try to test this functionality with a widget test, the future returned doesn't get resolved. Is there a way to mock the Clipboard.setData method?

Since my original code is quite large I made a reproducible widget test that has the same problem. The boolean dataCopied is false when I execute the expect().

testWidgets('test clipboard function', (WidgetTester tester) async {
    var dataCopied = false;
    await tester.pumpWidget(
      MaterialApp(
        home: Container(
          width: 10,
          height: 10,
          child: ElevatedButton(
            onPressed: (() {
              Clipboard.setData(ClipboardData(text: "test")).then((_) {
                dataCopied = true;
              });
            }),
            child: Text("Copy Text"),
          ),
        ),
      ),
    );

    await tester.tap(find.byType(ElevatedButton));
    expect(dataCopied, true);
  });

Solution

  • I found a solution. I checked the flutter source code and it seems the Clipboard class uses SystemChannels.platform to call the native clipboard function. From another post I saw that Channels can be mocked How can I mock/stub out a Flutter platform channel/plugin?

    testWidgets('test clipboard function', (WidgetTester tester) async {
        var dataCopied = false;
        
        final List<MethodCall> log = <MethodCall>[];
        SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
          log.add(methodCall);
        });
    
        await tester.pumpWidget(
          MaterialApp(
            home: Container(
              width: 10,
              height: 10,
              child: ElevatedButton(
                onPressed: (() {
                  Clipboard.setData(ClipboardData(text: "test")).then((_) {
                    dataCopied = true;
                  });
                }),
                child: Text("Copy Text"),
              ),
            ),
          ),
        );
    
        await tester.tap(find.byType(ElevatedButton));
        expect(dataCopied, true);
      });