Тест на флаттер — Принудительное восстановление виджета

#flutter #flutter-test #flutter-build

Вопрос:

Я пытаюсь написать тесты для своих виджетов flutter.

Допустим, у меня есть этот виджет с отслеживанием состояния:

 class A extends StatefulWidget {
  const A();
  
  @override
  AState createState() => AState();
}

class AState extends State<A> {
  bool value = false;

  @override
  Widget build(BuildContext context) {
    final newValue = getNewValue(); // When the widget is rebuilt, I'm getting a value which can be `false` or `true`. I just want the widget to perfom actions if it changed;
    if (value != newValue) {
      setState(() {
        value = newValue;
      });
      WidgetsBinding.instance.addPostFrameCallback((_) async {
        if (mounted) {
          // Do something, like show a snackbar for example
        }
      });
    }
    return const SizedBox.shrink();
  }
}
 

Когда виджет перестраивается, он смотрит getNewValue , изменилось ли значение, и перестраивает себя, а затем выполняет некоторые действия WidgetsBinding.instance.addPostFrameCallback . (Я хочу, чтобы виджет выполнял это действие только при перестройке, и в моем случае требуется не подписываться на getNewValue него).

В любом случае, я написал тест для этого и где я качаю виджет

 // Mock `getNewValue` here so it returns `true`
const widget = A();
await tester.pumpWidget(widget);
await tester.pump();
// Verify the action after the `WidgetsBinding.instance.addPostFrameCallback` as been done
 

что прекрасно работает.

Но теперь я хочу заставить виджет перестроиться, чтобы проверить его поведение.

Вот как мне удалось это сделать (я звоню setState ):

 // Mock `getNewValue` here so it returns `false` (change since last build)
tester.state<AState>(find.byType(A)).setState(() {});
await tester.pump();
await tester.pump();
// Verify the action after the `WidgetsBinding.instance.addPostFrameCallback` as been done
 

И это тоже прекрасно работает.


Однако вызов setState вызывает предупреждение

 The member 'setState' can only be used within instance members of subclasses of 'package:flutter/src/widgets/framework.dart'.dart(invalid_use_of_protected_member)
 

и этот трюк не сработает для StatelessWidget


Мне было интересно, как правильно заставить перестроить виджет в тесте flutter?