How to wait scheduled future with flutter_test?

Issue

My widget execute an asynchronous task and I want to check whether it is complete or not.

But it seems widget tester terminates the test before the task is executed. Whole code is here.

class MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    test();
  }

  Stream<int?> stream(Future<void> Function() worker) async* {
    Stream<int?> work() async* {
      await worker();
      yield 3;
    }

    yield* work();
  }

  Future<void> sampleWorker() async {
    throw Error();
  }

  Future<void> test() async {
    print('start');
    try {
      await for (final v in stream(sampleWorker)) {
        print(v);
      }
      print('point 1');
    } catch (error, stack) {
      print(stack);
    }
    print('done');
  }
}

void main() {
  testWidgets('Widget test', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(MyApp());
    await tester.pumpAndSettle(const Duration(milliseconds: 1000));
  });

  test('Plain test', () async {
    await MyHomePageState().test();
  });
}

I want both tests print stack trace, but only ‘Plain test’ shows expected behavior. The following is the log.

start
✓ Widget test
start
#0      MyHomePageState.sampleWorker (package:bug_report/main.dart:48:5)
#1      MyHomePageState.stream.work (package:bug_report/main.dart:40:19)
<asynchronous suspension>
#2      StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart)
<asynchronous suspension>

done
✓ Plain test

How to make first test prints stack trace? I should not await test() because it should be widget’s internal task.

Solution

Try WidgetTester‘s runAsync function to await an arbitrary amount of time for an internal widget’s async task to complete.

Answered By – moneer alhashim

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *