// Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { testWidgets('setState can be called from build, initState, didChangeDependencies, and didUpdateWidget', (WidgetTester tester) async { // Initial build. await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, child: TestWidget(value: 1), ), ); final _TestWidgetState state = tester.state(find.byType(TestWidget)); expect(state.calledDuringBuild, 1); expect(state.calledDuringInitState, 1); expect(state.calledDuringDidChangeDependencies, 1); expect(state.calledDuringDidUpdateWidget, 0); // Update Widget. late Widget child; await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: child = const TestWidget(value: 2), ), ); expect(state.calledDuringBuild, 2); // Increased. expect(state.calledDuringInitState, 1); expect(state.calledDuringDidChangeDependencies, 1); expect(state.calledDuringDidUpdateWidget, 1); // Increased. // Build after state is dirty. state.markNeedsBuild(); await tester.pump(); expect(state.calledDuringBuild, 3); // Increased. expect(state.calledDuringInitState, 1); expect(state.calledDuringDidChangeDependencies, 1); expect(state.calledDuringDidUpdateWidget, 1); // Change dependency. await tester.pumpWidget( Directionality( textDirection: TextDirection.rtl, // Changed. child: child, ), ); expect(state.calledDuringBuild, 4); // Increased. expect(state.calledDuringInitState, 1); expect(state.calledDuringDidChangeDependencies, 2); // Increased. expect(state.calledDuringDidUpdateWidget, 1); }); } class TestWidget extends StatefulWidget { const TestWidget({super.key, required this.value}); final int value; @override State createState() => _TestWidgetState(); } class _TestWidgetState extends State { int calledDuringBuild = 0; int calledDuringInitState = 0; int calledDuringDidChangeDependencies = 0; int calledDuringDidUpdateWidget = 0; void markNeedsBuild() { setState(() { // Intentionally left empty. }); } @override void initState() { super.initState(); setState(() { calledDuringInitState++; }); } @override void didChangeDependencies() { super.didChangeDependencies(); setState(() { calledDuringDidChangeDependencies++; }); } @override void didUpdateWidget(TestWidget oldWidget) { super.didUpdateWidget(oldWidget); setState(() { calledDuringDidUpdateWidget++; }); } @override Widget build(BuildContext context) { setState(() { calledDuringBuild++; }); return SizedBox.expand( child: Text(Directionality.of(context).toString()), ); } }