-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Describe the bug
After updating to riverpod 3.0.3, some widget tests are now failing that were not failing with riverpod 2.6.1. Curiously, some widget tests that use the same providers pass successfully. The application also works fine.
To Reproduce
Here is a standalone test that triggers an exception. It uses go_router to trigger a transition animation that causes the issue.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:go_router/go_router.dart';
final StreamProvider<bool> provider1 = StreamProvider<bool>((Ref ref) async* {
ref.watch(provider2);
yield true;
});
final FutureProvider<bool> provider2 = FutureProvider<bool>((Ref ref) async {
await Future<void>.sync(() {});
return true;
});
final StreamProvider<bool> provider3 = StreamProvider<bool>((Ref ref) async* {
await Future<void>.delayed(const Duration(milliseconds: 10));
yield true;
});
final Provider<bool> provider4 = Provider<bool>((Ref ref) {
final AsyncValue<bool> asyncValue = ref.watch(provider3);
if (asyncValue.value == null) {
return false;
}
return true;
});
void main() {
testWidgets('Riverpod should not cause exception', (
WidgetTester tester,
) async {
// Perform initialization before running the UI.
// Initialization needs to be run in true async environment.
final ProviderContainer container = ProviderContainer();
await tester.runAsync(() async {
// Read a future provider via listening to it.
final ProviderSubscription<Future<bool>> sub = container.listen(
provider1.future,
(_, _) {},
);
try {
return await sub.read();
} finally {
sub.close();
}
});
// Create router with a screen that watches a provider.
final GoRouter router = GoRouter(
routes: <RouteBase>[
GoRoute(
path: '/',
builder: (BuildContext context, GoRouterState state) {
return Consumer(
builder: (BuildContext context, WidgetRef ref, Widget? child) {
ref.watch(provider4);
return const SizedBox();
},
);
},
),
],
);
// Show the UI.
await tester.pumpWidget(
UncontrolledProviderScope(
container: container,
child: MaterialApp.router(routerConfig: router),
),
);
// Push second route to start a transition that shows the same screen twice.
unawaited(router.push('/'));
// Run the transition animation. Riverpod throws an exception here.
await tester.pumpAndSettle();
// Cleanup.
container.dispose();
});
}Test output with exception
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test:
setState() or markNeedsBuild() called during build.
This Consumer widget cannot be marked as needing to build because the framework is already in the
process of building widgets. A widget can be marked as needing to be built during the build phase
only if one of its ancestors is currently building. This exception is allowed because the framework
builds parent widgets before children, which means a dirty descendant will always be built.
Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was:
Consumer
The widget which was currently being built when the offending call was made was:
Consumer
When the exception was thrown, this was the stack:
#0 Element.markNeedsBuild. (package:flutter/src/widgets/framework.dart:5279:9)
#1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:5291:6)
#2 ConsumerStatefulElement.watch.. (package:flutter_riverpod/src/core/consumer.dart:453:28)
#3 InternalProviderContainer.runBinaryGuarded (package:riverpod/src/core/provider_container.dart:679:9)
#4 ProviderSubscriptionImpl._notifyData (package:riverpod/src/core/provider_subscription.dart:181:32)
#5 InternalProviderContainer.runBinaryGuarded (package:riverpod/src/core/provider_container.dart:679:9)
#6 ProviderElement._notifyListeners (package:riverpod/src/core/element.dart:820:21)
#7 ProviderElement._performRebuild (package:riverpod/src/core/element.dart:582:9)
#8 ProviderElement.flush (package:riverpod/src/core/element.dart:626:7)
#9 $ProviderBaseImpl._addListener (package:riverpod/src/core/provider/provider.dart:117:24)
#10 ProviderContainer.listen (package:riverpod/src/core/provider_container.dart:954:26)
#11 ConsumerStatefulElement.watch. (package:flutter_riverpod/src/core/consumer.dart:451:37)
#12 _LinkedHashMapMixin.putIfAbsent (dart:_compact_hash:674:23)
#13 ConsumerStatefulElement.watch (package:flutter_riverpod/src/core/consumer.dart:444:14)
#14 main... (file:///home/karel/apps/theme/test/src/domain/failing_test.dart:60:21)
#15 Consumer.build (package:flutter_riverpod/src/core/consumer.dart:182:19)
#16 _ConsumerState.build (package:flutter_riverpod/src/core/consumer.dart:283:48)
#17 StatefulElement.build (package:flutter/src/widgets/framework.dart:5833:27)
#18 ConsumerStatefulElement.build (package:flutter_riverpod/src/core/consumer.dart:421:20)
#19 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5723:15)
#20 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5884:11)
#21 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#22 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5705:5)
#23 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5875:11)
#24 ComponentElement.mount (package:flutter/src/widgets/framework.dart:5699:5)
... Normal element mounting (234 frames)
#258 Element.inflateWidget (package:flutter/src/widgets/framework.dart:4548:16)
#259 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:7169:36)
#260 Element.updateChild (package:flutter/src/widgets/framework.dart:4004:18)
#261 Element.updateChildren (package:flutter/src/widgets/framework.dart:4203:32)
#262 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:7202:17)
#263 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#264 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#265 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5884:11)
#266 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#267 StatefulElement.update (package:flutter/src/widgets/framework.dart:5909:5)
#268 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#269 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#270 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#271 ProxyElement.update (package:flutter/src/widgets/framework.dart:6051:5)
#272 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#273 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#274 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#275 ProxyElement.update (package:flutter/src/widgets/framework.dart:6051:5)
#276 _InheritedNotifierElement.update (package:flutter/src/widgets/inherited_notifier.dart:108:11)
#277 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#278 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#279 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5884:11)
#280 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#281 StatefulElement.update (package:flutter/src/widgets/framework.dart:5909:5)
#282 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#283 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#284 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#285 ProxyElement.update (package:flutter/src/widgets/framework.dart:6051:5)
#286 _InheritedNotifierElement.update (package:flutter/src/widgets/inherited_notifier.dart:108:11)
#287 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#288 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#289 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5884:11)
#290 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#291 StatefulElement.update (package:flutter/src/widgets/framework.dart:5909:5)
#292 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#293 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#294 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5884:11)
#295 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#296 StatefulElement.update (package:flutter/src/widgets/framework.dart:5909:5)
#297 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#298 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:7025:14)
#299 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#300 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:7025:14)
#301 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#302 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#303 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#304 ProxyElement.update (package:flutter/src/widgets/framework.dart:6051:5)
#305 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#306 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#307 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#308 ProxyElement.update (package:flutter/src/widgets/framework.dart:6051:5)
#309 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#310 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#311 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5884:11)
#312 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#313 StatefulElement.update (package:flutter/src/widgets/framework.dart:5909:5)
#314 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#315 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#316 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#317 ProxyElement.update (package:flutter/src/widgets/framework.dart:6051:5)
#318 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#319 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#320 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#321 ProxyElement.update (package:flutter/src/widgets/framework.dart:6051:5)
#322 _InheritedNotifierElement.update (package:flutter/src/widgets/inherited_notifier.dart:108:11)
#323 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#324 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#325 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5884:11)
#326 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#327 StatefulElement.update (package:flutter/src/widgets/framework.dart:5909:5)
#328 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#329 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#330 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#331 ProxyElement.update (package:flutter/src/widgets/framework.dart:6051:5)
#332 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#333 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#334 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#335 StatelessElement.update (package:flutter/src/widgets/framework.dart:5797:5)
#336 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#337 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#338 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#339 ProxyElement.update (package:flutter/src/widgets/framework.dart:6051:5)
#340 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#341 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#342 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#343 ProxyElement.update (package:flutter/src/widgets/framework.dart:6051:5)
#344 Element.updateChild (package:flutter/src/widgets/framework.dart:3982:15)
#345 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5747:16)
#346 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5884:11)
#347 Element.rebuild (package:flutter/src/widgets/framework.dart:5435:7)
#348 BuildScope._tryRebuild (package:flutter/src/widgets/framework.dart:2695:15)
#349 BuildScope._flushDirtyElements (package:flutter/src/widgets/framework.dart:2752:11)
#350 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:3056:18)
#351 AutomatedTestWidgetsFlutterBinding.drawFrame (package:flutter_test/src/binding.dart:1506:19)
#352 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:495:5)
#353 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1434:15)
#354 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1347:9)
#355 AutomatedTestWidgetsFlutterBinding.pump. (package:flutter_test/src/binding.dart:1335:9)
#358 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:74:41)
#359 AutomatedTestWidgetsFlutterBinding.pump (package:flutter_test/src/binding.dart:1324:27)
#360 WidgetTester.pumpAndSettle. (package:flutter_test/src/widget_tester.dart:719:23)
#363 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:74:41)
#364 WidgetTester.pumpAndSettle (package:flutter_test/src/widget_tester.dart:712:27)
#365 main. (file:///home/karel/apps/theme/test/src/domain/failing_test.dart:80:18)
#366 testWidgets.. (package:flutter_test/src/widget_tester.dart:192:15)
#367 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:1059:5)
(elided 5 frames from dart:async and package:stack_trace)
The test description was:
Riverpod should not cause exception
Expected behavior
Riverpod should not cause an exception in tests.
If this is a bug in the test code, the exception should direct developer to the potential mistake.