Widget testing for Flushbar with duration
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?
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
@stevanusw28 Did you later find a way to test the Flushbar?
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