Flutter widget test Clipboard.setData future then never triggered

Issue

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);
  });

Answered By – Stan

Answer Checked By – Mildred Charles (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.