2017-02-24 1 views
1

Ich habe ein Widget, das, wenn geklickt wird, speichert eine ID-Nummer, überlagert einen CircularProgressIndicator für 1000ms und dann die Fortschrittsanzeige Pop und leitet den Benutzer auf eine andere Seite.Wie kann ich einen Komponententest ausführen, wenn das angetippte Widget einen Timer startet?

Dieses Bit mit dem Progress und der Timer neu ist und meine Unit-Test gebrochen, die nun mir die folgende Störung gibt:

The following assertion was thrown running a test: 
'package:flutter_test/src/binding.dart': Failed assertion: line 574 pos 12: '() { 
     'A Timer is still pending even after the widget tree was disposed.'; 
     return _fakeAsync.nonPeriodicTimerCount == 0; 
    }': is not true. 

Either the assertion indicates an error in the framework itself, or we should provide substantially 
more information in this error message to help you determine and fix the underlying cause. 
In either case, please report this assertion by filing a bug on GitHub: 
    https://github.com/flutter/flutter/issues/new 

When the exception was thrown, this was the stack: 
#2  AutomatedTestWidgetsFlutterBinding._verifyInvariants (package:flutter_test/src/binding.dart:574:12) 
#3  TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:415:7) 
<asynchronous suspension> 
#7  TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:392:14) 
#8  AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:549:24) 
#14  AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:547:16) 
#15  testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:54:50) 
#16  Declarer.test.<anonymous closure>.<anonymous closure> (package:test/src/backend/declarer.dart:131:19) 
<asynchronous suspension> 
#17  Invoker.waitForOutstandingCallbacks.<anonymous closure>.<anonymous closure> (package:test/src/backend/invoker.dart:200:17) 
<asynchronous suspension> 
#22  Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test/src/backend/invoker.dart:197:7) 
#26  Invoker.waitForOutstandingCallbacks (package:test/src/backend/invoker.dart:196:5) 
#27  Declarer.test.<anonymous closure> (package:test/src/backend/declarer.dart:129:29) 
<asynchronous suspension> 
#28  Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test/src/backend/invoker.dart:322:23) 
<asynchronous suspension> 
#43  _Timer._runTimers (dart:isolate-patch/timer_impl.dart:385) 
#44  _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414) 
#45  _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148) 
(elided 31 frames from class _AssertionError, class _FakeAsync, package dart:async, package 
dart:async-patch, and package stack_trace) 

Dies ist, was die gebrochene Test wie folgt aussieht:

testWidgets('Tapping item saves its id', (WidgetTester tester) async { 
    await launchApp(item, tester); 
    await tester.tap(find.byConfig(item)); 

    expect(sameId(global_state.currentId, item.id), isTrue); 
}); 

Gibt es eine Möglichkeit, eine Verzögerung einzuführen, bevor der Widget-Baum entfernt wird? Was sind meine anderen Optionen? Oder irre ich mich mit der Ursache des Problems?

Antwort

2

testWidgets führt automatisch eine FakeAsync-Zone ein, mit der Sie die Zeit durchgehen können. Verwenden Sie pump, um Zeit zu erhöhen.

Der Fehler, den Sie sehen, liegt daran, dass Ihr Widget den Timer nicht abstellt, wenn er entsorgt wird. Stellen Sie sicher, dass Ihre Widget-Objekte niemals Ressourcen (wie Timer) zuweisen und dass Ihre State-Objekte in der dispose-Methode immer alle Ressourcen bereinigen, die sie zuweisen.

Verwandte Themen