another-flushbar icon indicating copy to clipboard operation
another-flushbar copied to clipboard

Widget testing for Flushbar with duration

Open stevanusw28 opened this issue 4 years ago • 3 comments

Hello, I try to create the widget test for the flushbar component (with duration). However, is seems there is timer that block the process like this:

Pending timers: Timer (duration: 0:00:02.000000, periodic: false), created: #0 new FakeTimer._ (package:fake_async/fake_async.dart:284:41) #1 FakeAsync._createTimer (package:fake_async/fake_async.dart:248:27) #2 FakeAsync.run. (package:fake_async/fake_async.dart:181:19) #5 FlushbarRoute._configureTimer (package:another_flushbar/flushbar_route.dart:393:16) #6 FlushbarRoute.didPush (package:another_flushbar/flushbar_route.dart:347:5) #7 _RouteEntry.handlePush (package:flutter/src/widgets/navigator.dart:3013:46) #8 NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:3958:17) #9 NavigatorState._pushEntry (package:flutter/src/widgets/navigator.dart:4573:5) #10 NavigatorState.push (package:flutter/src/widgets/navigator.dart:4480:5) #11 Flushbar.show (package:another_flushbar/flushbar.dart:267:10) #12 _RandomUserScreenState._buildGenerateButton. (package:feature_user/presentation/views/random_user_screen.dart:110:15) (elided 2 frames from dart:async)

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════ The following assertion was thrown running a test (but after the test had completed): A Timer is still pending even after the widget tree was disposed. 'package:flutter_test/src/binding.dart': Failed assertion: line 1245 pos 12: '!timersPending'

When the exception was thrown, this was the stack: #2 AutomatedTestWidgetsFlutterBinding._verifyInvariants (package:flutter_test/src/binding.dart:1245:12) #3 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:806:7) (elided 2 frames from class _AssertionError)

Because of this, I can only expect the flushbar value just after the timer process done like this:

      // Duration of flushbar is 2 second
      await tester.pumpAndSettle(Duration(seconds: 2));
      final flushbarSuccess = find.text("Successfully added");
      expect(flushbarSuccess, findsOneWidget);

However, this will give the test result is failed because the flushbarSuccess already dismissed after 2 second. Is there any way to test the Flushbar?

stevanusw28 avatar Jul 27 '21 08:07 stevanusw28

Depends on your implementation, is there only Flushbar with duration 2 sec ? or you have some Timer(...);

in my case i added difference -1 second and add pump again after expect , and finally works

Example :

// My Snackbar

Flushbar(
            title: 'Hey Ninja',
            message:
                'Lorem Ipsum is simply dummy text of the printing and typesetting industry',
            duration: Duration(seconds: 3),
          ).show(context);

// Widget Test

await tester.pump(Duration(seconds: 2));
      final flushbarSuccess = find.text("Hey Ninja");
      expect(flushbarSuccess, findsOneWidget);
await tester.pump(Duration(seconds: 2));

gap 1 seconds means to execute matcher before flush bar is gone

kharisazhar avatar Sep 06 '21 17:09 kharisazhar

@stevanusw28 Did you later find a way to test the Flushbar?

JideGuru avatar Nov 16 '21 19:11 JideGuru

Depends on your implementation, is there only Flushbar with duration 2 sec ? or you have some Timer(...);

in my case i added difference -1 second and add pump again after expect , and finally works

Example :

// My Snackbar

Flushbar(
            title: 'Hey Ninja',
            message:
                'Lorem Ipsum is simply dummy text of the printing and typesetting industry',
            duration: Duration(seconds: 3),
          ).show(context);

// Widget Test

await tester.pump(Duration(seconds: 2));
      final flushbarSuccess = find.text("Hey Ninja");
      expect(flushbarSuccess, findsOneWidget);
await tester.pump(Duration(seconds: 2));

gap 1 seconds means to execute matcher before flush bar is gone

This solution at least not working for me.

In my implementation, the flushbar is wrapped by WidgetsBinding.instance!.addPostFrameCallback(). Already tried using tester.binding.scheduleFrame() and tester.binding.scheduleWarmUpFrame() but still not working

source: https://stackoverflow.com/questions/57612693/widget-test-a-widget-which-uses-widgetsbinding-instance-addpostframecallback

tijanirf avatar Mar 30 '22 07:03 tijanirf