#animation #widget #widget-test-flutter
#Анимация #виджет #виджет-тест-flutter
Вопрос:
У меня есть тест виджета, похожий на:
testWidgets('Widget test', (WidgetTester tester) async {
provideMockedNetworkImages(() async {
final widget = MyWidget();
await WidgetTestFunctions.pumpWidgetTest(
tester,
widget,
);
// ....
await tester.tap(find.byType(MyWidget));
await tester.pump(new Duration(milliseconds: 3000));
// ....
expect(widget.value, myValue);
});
});
И следующая реализация метода on-tap виджета:
_onButtonPressed() async {
await animationController.forward();
setState(() {
// ...
// Calls method that changes the widget value.
});
}
Проблема, с которой я сталкиваюсь, заключается в том, что после вызова animationController.forward()
метода в тесте setState
часть не выполняется. Как мне дождаться корректного завершения этого метода? Во время выполнения приложения эта часть кода вызывается правильно.
Похоже await tester.pump(new Duration(milliseconds: 3000));
, что он работает некорректно, анимация длится 1500 миллисекунд, и, как вы можете видеть, продолжительность накачки удваивается.
Комментарии:
1. Вы узнали, каков был ответ?
2. @SilkeNL еще нет
3. Вы пробовали перекачку без продолжительности?
await tester.tap(find.byType(MyWidget)); await tester.pump(new Duration(milliseconds: 3000));
4. У меня была похожая проблема, когда я не мог найти виджет после
AnimationController.forward
вызова. Я «исправил» это, назначив aValueKey
виджету, который я хочу протестировать, а затем используя этот ключ для проверки информации. Однако это не решение проблемы, а скорее хак.5. Привет @notarealgreal вы все еще не нашли никакого решения для этого?
Ответ №1:
Вместо await tester.pump(new Duration(milliseconds: 3000));
попытки ожидания tester.pumpAndSettle();
этот тип перекачки ожидает окончания анимации, а затем перекачивает кадры.
Ответ №2:
У меня была такая же проблема, и вот что происходило.
Когда вы сделаете
await animationController.forward();
Вы не ожидаете простого Future<void>
завершения, а TickerFuture
(расширяется Future<void>
).
По какой-то причине в моих тестах некоторые TickerFuture
s из animationController.forward()
weere отменены.
В документе TickerProvider
говорится:
Если тикер удален без остановки или если он остановлен с отмененным значением true, то это будущее никогда не завершится.
Этот класс работает как обычный Future, но имеет дополнительное свойство orCancel, которое возвращает производное Future, которое завершается с ошибкой, если тикер, который вернул TickerFuture, был остановлен с cancelled, установленным в true, или если он был удален без остановки.
Чтобы выполнить обратный вызов, когда либо это будущее разрешится, либо когда тикер отменен, используйте whenCompleteOrCancel .
Теперь проблема в whenCompleteOrCancel
том, что он возвращается void
(и не Future<void>
поэтому мы не можем его дождаться.
Итак, вот что я сделал (вдохновленный реализацией whenCompleteOrCancel
):
Future<void> thunk(dynamic value) {
return;
}
final TickerFuture ticker = animationController.forward();
await ticker.onCancel.then(thunk, onError: thunk); // <- This resolves even if the ticker is canceled and the tests are not stuck anymore.