😇
EXCEPTION CAUGHT BY WIDGETS LIBRARY
WidgetTest Error
簡単な、WidgetTestをしたらエラーが発生した😅
なぜだ.....
表示するWidget
todo_view.dart
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
()
class TodoView extends HookConsumerWidget {
const TodoView({super.key});
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(
title: const Text('Todo'),
),
body: const Center(
child: Text('Todo'),
),
);
}
}
[error code]
/Users/jboy422/development/flutter/bin/flutter --no-color test --machine --start-paused test/todo_view_test.dart
Testing started at 20:41 ...
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building Scaffold(dirty, state: ScaffoldState#666ee(tickers:
tracking 2 tickers)):
No Directionality widget found.
Scaffold widgets require a Directionality widget ancestor.
The specific widget that could not find a Directionality ancestor was:
Scaffold
The ownership chain for the affected widget is: "Scaffold ← TodoView ← MediaQuery ←
_MediaQueryFromView ← _PipelineOwnerScope ← _ViewScope ← _RawView-[_DeprecatedRawViewKey
TestFlutterView#3c7b9] ← View ← [root]"
Typically, the Directionality widget is introduced by the MaterialApp or WidgetsApp widget at the
top of your application widget tree. It determines the ambient reading direction and is used, for
example, to determine how to lay out text, how to interpret "start" and "end" values, and to resolve
EdgeInsetsDirectional, AlignmentDirectional, and other *Directional objects.
The relevant error-causing widget was:
Scaffold
Scaffold:file:///Users/MY_PJ/KMP_PJ/supabase_example/lib/presentation/todo/todo_view.dart:11:12
When the exception was thrown, this was the stack:
#0 debugCheckHasDirectionality.<anonymous closure> (package:flutter/src/widgets/debug.dart:353:7)
#1 debugCheckHasDirectionality (package:flutter/src/widgets/debug.dart:373:4)
#2 ScaffoldState.build (package:flutter/src/material/scaffold.dart:2849:12)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:5599:27)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5487:15)
#5 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5650:11)
#6 Element.rebuild (package:flutter/src/widgets/framework.dart:5203:7)
#7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5469:5)
#8 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5641:11)
#9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:5463:5)
... Normal element mounting (9 frames)
#18 Element.inflateWidget (package:flutter/src/widgets/framework.dart:4340:16)
#19 Element.updateChild (package:flutter/src/widgets/framework.dart:3843:20)
#20 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5512:16)
#21 Element.rebuild (package:flutter/src/widgets/framework.dart:5203:7)
#22 ProxyElement.update (package:flutter/src/widgets/framework.dart:5816:5)
#23 Element.updateChild (package:flutter/src/widgets/framework.dart:3827:15)
#24 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5512:16)
#25 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5650:11)
#26 Element.rebuild (package:flutter/src/widgets/framework.dart:5203:7)
#27 StatefulElement.update (package:flutter/src/widgets/framework.dart:5673:5)
#28 Element.updateChild (package:flutter/src/widgets/framework.dart:3827:15)
#29 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5512:16)
#30 Element.rebuild (package:flutter/src/widgets/framework.dart:5203:7)
#31 ProxyElement.update (package:flutter/src/widgets/framework.dart:5816:5)
#32 Element.updateChild (package:flutter/src/widgets/framework.dart:3827:15)
#33 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5512:16)
#34 Element.rebuild (package:flutter/src/widgets/framework.dart:5203:7)
#35 ProxyElement.update (package:flutter/src/widgets/framework.dart:5816:5)
#36 Element.updateChild (package:flutter/src/widgets/framework.dart:3827:15)
#37 _RawViewElement._updateChild (package:flutter/src/widgets/view.dart:291:16)
#38 _RawViewElement.update (package:flutter/src/widgets/view.dart:378:5)
#39 Element.updateChild (package:flutter/src/widgets/framework.dart:3827:15)
#40 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5512:16)
#41 Element.rebuild (package:flutter/src/widgets/framework.dart:5203:7)
#42 StatelessElement.update (package:flutter/src/widgets/framework.dart:5563:5)
#43 Element.updateChild (package:flutter/src/widgets/framework.dart:3827:15)
#44 RootElement._rebuild (package:flutter/src/widgets/binding.dart:1581:16)
#45 RootElement.update (package:flutter/src/widgets/binding.dart:1559:5)
#46 RootElement.performRebuild (package:flutter/src/widgets/binding.dart:1573:7)
#47 Element.rebuild (package:flutter/src/widgets/framework.dart:5203:7)
#48 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2905:19)
#49 AutomatedTestWidgetsFlutterBinding.drawFrame (package:flutter_test/src/binding.dart:1418:19)
#50 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:443:5)
#51 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1392:15)
#52 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1313:9)
#53 AutomatedTestWidgetsFlutterBinding.pump.<anonymous closure> (package:flutter_test/src/binding.dart:1273:9)
#56 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#57 AutomatedTestWidgetsFlutterBinding.pump (package:flutter_test/src/binding.dart:1260:27)
#58 WidgetTester.pumpWidget.<anonymous closure> (package:flutter_test/src/widget_tester.dart:602:22)
#61 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#62 WidgetTester.pumpWidget (package:flutter_test/src/widget_tester.dart:599:27)
#63 main.<anonymous closure> (file:///Users/MY_PJ/KMP_PJ/supabase_example/test/todo_view_test.dart:7:18)
#64 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:183:29)
<asynchronous suspension>
#65 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:1017:5)
<asynchronous suspension>
<asynchronous suspension>
(elided 5 frames from dart:async and package:stack_trace)
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: TodoView is displayed
「Github Copilotよ、俺ちゃんに力を」
厨二病みたいですね笑
テスト中にDirectionalityウィジェットが見つからないというエラーが発生しています。これは、Scaffoldなどの一部のウィジェットが、テキストの配置などを決定するためにDirectionalityウィジェットを必要とするためです。通常、DirectionalityウィジェットはMaterialAppまたはWidgetsAppウィジェットによって提供されます。 テスト中にこのエラーが発生する場合、テストでウィジェットを作成するときにMaterialAppを含めることで解決できます。以下に修正したテストコードを示します。
test/todo_view_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:supabase_example/presentation/todo/todo_view.dart';
import 'package:flutter/material.dart';
void main() {
testWidgets('TodoView is displayed', (WidgetTester tester) async {
// Build our app and trigger a frame.
// アプリをビルドしてフレームをトリガーします。
await tester.pumpWidget(const MaterialApp(home: TodoView()));
// Verify that TodoView is displayed.
// TodoViewが表示されていることを確認します。
expect(find.byType(TodoView), findsOneWidget);
});
}
テストが通ったようだ 😅
まとめ
WidgetTestするときは、 MaterialApp
を使いましょう!
MaterialApp
でテストするWidgetをWrapすること。これがポイントです。
Discussion