我正在为此项目使用颤音小部件测试,我想测试TextFormField验证是否有效,但找不到上下文
这是测试代码`
testWidgets('invalid input for testtwo', (WidgetTester tester) async {
final test_two = find.byKey(ValueKey('test2'));
final fill_mark = find.byKey(ValueKey('fillmark'));
await tester.pumpWidget(PopUpMarklist(id: 'someid'));
await tester.enterText(test_two, '12');
await tester.tap(fill_mark);
await tester.pump();
expect(find.text('please put the extra marks in the other section'),
findsOneWidget);
expect(find.text('please fill the result if no result just put 0.0'),
findsNothing);
});`
,bloc提供商位于主
...
MaterialApp(
home: MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => Teacher_bloc(TeacherUserRepository(
teacherProvider: TeacherUserRemoteProvider()))
..add(LoadTeacher()),
),
BlocProvider(
create: (context) =>
MarklistBloc(MarklistRepository(MarklistRemoteProvider())),
),
BlocProvider(create: (ctx) => AuthBloc(authRepository)),
BlocProvider<ParAccBloc>(
create: (context) =>
ParAccBloc(ParentRepository(parentProvider: ParentApiProvider()))
..add(LoadParAccs()),
),
BlocProvider(
create: (context) => TeacherAccBloc(
TeacherRepository(teacherProvider: TeacherApiProvider()),
)..add(LoadTeacherAccs()),
),
BlocProvider<AnnouncemntBloc>(
create: (context) => AnnouncemntBloc(
announcemntRepository: AnnouncemntRepository(
dataProvider: AnnouncemntDataProvider(
httpClient: http.Client(),
)))
..add(AnnouncemntLoad())),
],
child: MaterialApp.router(
theme: currTheme,
routeInformationParser: _router.routeInformationParser,
routerDelegate: _router.routerDelegate,
title: "sms-demo",
),
))`
。
``
class PopUpMarklist extends StatefulWidget {
String id;
Marklist? marklist;
PopUpMarklist({Key? key, required this.id, this.marklist}) : super(key: key);
@override
State<PopUpMarklist> createState() => PopUpMarklistState();
}
class PopUpMarklistState extends State<PopUpMarklist> {
final formKey = GlobalKey<FormState>();
final testOneController = TextEditingController();
final testTwoController = TextEditingController();
@override
Widget build(BuildContext context) {
return BlocConsumer<MarklistBloc, MarklistState>(
listener: (context, state) {
if (state is StudentMarkReturned) {
testOneController.text = state.studentMark.testOne.toString();
testTwoController.text = state.studentMark.testTwo.toString();
}
},
builder: (context, state) {
return Form(
key: formKey,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextFormField(
key: Key('test1'),
controller: testOneController,
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
style: const TextStyle(
color: Color.fromARGB(255, 84, 81, 71),
),
decoration: const InputDecoration(
hintText: 'Test one (10%)',
focusColor: Color.fromARGB(255, 84, 81, 71),
),
validator: (String? testOne) {
if (testOne == null || testOne.isEmpty) {
return 'please fill the result if no result just put 0.0';
}
var test10 = double.parse(testOne);
if (test10 > 10) {
return 'please put the extra marks in the other section';
}
return null;
},
),
TextFormField(
key: Key('test2'),
keyboardType: TextInputType.number,
controller: testTwoController,
textAlign: TextAlign.center,
style: const TextStyle(
color: Color.fromARGB(255, 84, 81, 71),
),
decoration: const InputDecoration(
hintText: 'Test two (10%)',
focusColor: Color.fromARGB(255, 84, 81, 71),
),
validator: (String? testTwo) {
if (testTwo == null || testTwo.isEmpty) {
return 'please fill the result if no result just put 0.0';
}
var test10 = double.parse(testTwo);
if (test10 > 10) {
return 'please put the extra marks in the other section';
}
return null;
},
),
ElevatedButton(
key: Key('fillmark'),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
const Color.fromARGB(255, 106, 104, 99)),
),
onPressed: () {
final formValid = formKey.currentState!.validate();
if (!formValid) return;
final marklistBloc = BlocProvider.of<MarklistBloc>(context);
marklistBloc.add(Edit(
studentId: widget.id,
testtwo: int.parse(testtwoController.text),
;
GoRouter.of(context).pushNamed("teacher homepage");
},
child: Text("submit"),
)
],
),
),
);
},
)}}
`` 这是在调试控制台中丢下的错误
`══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following ProviderNotFoundException was thrown building PopUpMarklist(state:
PopUpMarklistState#96199):
Error: Could not find the correct Provider<MarklistBloc> above this BlocConsumer<MarklistBloc,
MarklistState> Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that BlocConsumer<MarklistBloc, MarklistState> is under your
MultiProvider/Provider<MarklistBloc>.
This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>().toString()),
);
}
```
consider using `builder` like so:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context, child) {
// No longer throws
return Text(context.watch<Example>().toString());
}
);
}
```
If none of these solutions work, consider asking for help on StackOverflow:
https://stackoverflow.com/questions/tagged/flutter
The relevant error-causing widget was:
PopUpMarklist
PopUpMarklist:file:///C:/Users/Yosep/OneDrive/Desktop/flutter%20project/sms_demo/test/fillMarklist_test.dart:26:29
When the exception was thrown, this was the stack:
#0 Provider._inheritedElementOf (package:provider/src/provider.dart:343:7)
#1 Provider.of (package:provider/src/provider.dart:293:30)
#2 ReadContext.read (package:provider/src/provider.dart:649:21)
#3 _BlocConsumerState.initState (package:flutter_bloc/src/bloc_consumer.dart:108:36)
#4 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4893:57)
#5 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4729:5)
... Normal element mounting (9 frames)
#14 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3790:14)
#15 Element.updateChild (package:flutter/src/widgets/framework.dart:3524:20)
#16 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1198:16)
#17 RenderObjectToWidgetElement.update (package:flutter/src/widgets/binding.dart:1175:5)
#18 RenderObjectToWidgetElement.performRebuild (package:flutter/src/widgets/binding.dart:1189:7)
#19 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#20 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2659:19)
#21 AutomatedTestWidgetsFlutterBinding.drawFrame (package:flutter_test/src/binding.dart:1128:19)
#22 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5)
#23 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1144:15)
#24 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1081:9)
#25 AutomatedTestWidgetsFlutterBinding.pump.<anonymous closure> (package:flutter_test/src/binding.dart:995:9)
#28 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#29 AutomatedTestWidgetsFlutterBinding.pump (package:flutter_test/src/binding.dart:982:27)
#30 WidgetTester.pumpWidget.<anonymous closure> (package:flutter_test/src/widget_tester.dart:548:22)
#33 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#34 WidgetTester.pumpWidget (package:flutter_test/src/widget_tester.dart:545:27)
#35 main.<anonymous closure> (file:///C:/Users/Yosep/OneDrive/Desktop/flutter%20project/sms_demo/test/fillMarklist_test.dart:26:18)
#36 main.<anonymous closure> (file:///C:/Users/Yosep/OneDrive/Desktop/flutter%20project/sms_demo/test/fillMarklist_test.dart:22:44)
#37 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:170:29)
<asynchronous suspension>
<asynchronous suspension>
(elided 5 frames from dart:async and package:stack_trace)
════════════════════════════════════════════════════════════════════════════════════════════════════
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following StateError was thrown running a test:
Bad state: No element
When the exception was thrown, this was the stack:
#0 Iterable.single (dart:core/iterable.dart:654:25)
#1 WidgetController.state (package:flutter_test/src/controller.dart:156:42)
#2 WidgetTester.showKeyboard.<anonymous closure> (package:flutter_test/src/widget_tester.dart:1042:42)
#3 WidgetTester.showKeyboard.<anonymous closure> (package:flutter_test/src/widget_tester.dart:1041:39)
#6 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#7 WidgetTester.showKeyboard (package:flutter_test/src/widget_tester.dart:1041:27)
#8 WidgetTester.enterText.<anonymous closure> (package:flutter_test/src/widget_tester.dart:1077:13)
#9 WidgetTester.enterText.<anonymous closure> (package:flutter_test/src/widget_tester.dart:1076:39)
#12 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#13 WidgetTester.enterText (package:flutter_test/src/widget_tester.dart:1076:27)
#14 main.<anonymous closure> (file:///C:/Users/Yosep/OneDrive/Desktop/flutter%20project/sms_demo/test/fillMarklist_test.dart:27:18)
<asynchronous suspension>
<asynchronous suspension>
(elided 5 frames from dart:async and package:stack_trace)
The test description was:
invalid input for testtwo
════════════════════════════════════════════════════════════════════════════════════════════════════
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following message was thrown:
Multiple exceptions (2) were detected during the running of the current test, and at least one was
unexpected.
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: invalid input for testtwo
✖ invalid input for testtwo
Exited (1)
``
我使用Go Router用路路由,因此如何解决此问题,请事先解决此问题。
this is the test code `
testWidgets('invalid input for testtwo', (WidgetTester tester) async {
final test_two = find.byKey(ValueKey('test2'));
final fill_mark = find.byKey(ValueKey('fillmark'));
await tester.pumpWidget(PopUpMarklist(id: 'someid'));
await tester.enterText(test_two, '12');
await tester.tap(fill_mark);
await tester.pump();
expect(find.text('please put the extra marks in the other section'),
findsOneWidget);
expect(find.text('please fill the result if no result just put 0.0'),
findsNothing);
});`
and the bloc provider is in the main.dart as follows `
...
MaterialApp(
home: MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => Teacher_bloc(TeacherUserRepository(
teacherProvider: TeacherUserRemoteProvider()))
..add(LoadTeacher()),
),
BlocProvider(
create: (context) =>
MarklistBloc(MarklistRepository(MarklistRemoteProvider())),
),
BlocProvider(create: (ctx) => AuthBloc(authRepository)),
BlocProvider<ParAccBloc>(
create: (context) =>
ParAccBloc(ParentRepository(parentProvider: ParentApiProvider()))
..add(LoadParAccs()),
),
BlocProvider(
create: (context) => TeacherAccBloc(
TeacherRepository(teacherProvider: TeacherApiProvider()),
)..add(LoadTeacherAccs()),
),
BlocProvider<AnnouncemntBloc>(
create: (context) => AnnouncemntBloc(
announcemntRepository: AnnouncemntRepository(
dataProvider: AnnouncemntDataProvider(
httpClient: http.Client(),
)))
..add(AnnouncemntLoad())),
],
child: MaterialApp.router(
theme: currTheme,
routeInformationParser: _router.routeInformationParser,
routerDelegate: _router.routerDelegate,
title: "sms-demo",
),
))`
the provider is in the main.dart ,i thought this code(PopUpMarklist) which is in an other file , will be able to access it.
`
class PopUpMarklist extends StatefulWidget {
String id;
Marklist? marklist;
PopUpMarklist({Key? key, required this.id, this.marklist}) : super(key: key);
@override
State<PopUpMarklist> createState() => PopUpMarklistState();
}
class PopUpMarklistState extends State<PopUpMarklist> {
final formKey = GlobalKey<FormState>();
final testOneController = TextEditingController();
final testTwoController = TextEditingController();
@override
Widget build(BuildContext context) {
return BlocConsumer<MarklistBloc, MarklistState>(
listener: (context, state) {
if (state is StudentMarkReturned) {
testOneController.text = state.studentMark.testOne.toString();
testTwoController.text = state.studentMark.testTwo.toString();
}
},
builder: (context, state) {
return Form(
key: formKey,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextFormField(
key: Key('test1'),
controller: testOneController,
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
style: const TextStyle(
color: Color.fromARGB(255, 84, 81, 71),
),
decoration: const InputDecoration(
hintText: 'Test one (10%)',
focusColor: Color.fromARGB(255, 84, 81, 71),
),
validator: (String? testOne) {
if (testOne == null || testOne.isEmpty) {
return 'please fill the result if no result just put 0.0';
}
var test10 = double.parse(testOne);
if (test10 > 10) {
return 'please put the extra marks in the other section';
}
return null;
},
),
TextFormField(
key: Key('test2'),
keyboardType: TextInputType.number,
controller: testTwoController,
textAlign: TextAlign.center,
style: const TextStyle(
color: Color.fromARGB(255, 84, 81, 71),
),
decoration: const InputDecoration(
hintText: 'Test two (10%)',
focusColor: Color.fromARGB(255, 84, 81, 71),
),
validator: (String? testTwo) {
if (testTwo == null || testTwo.isEmpty) {
return 'please fill the result if no result just put 0.0';
}
var test10 = double.parse(testTwo);
if (test10 > 10) {
return 'please put the extra marks in the other section';
}
return null;
},
),
ElevatedButton(
key: Key('fillmark'),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
const Color.fromARGB(255, 106, 104, 99)),
),
onPressed: () {
final formValid = formKey.currentState!.validate();
if (!formValid) return;
final marklistBloc = BlocProvider.of<MarklistBloc>(context);
marklistBloc.add(Edit(
studentId: widget.id,
testtwo: int.parse(testtwoController.text),
;
GoRouter.of(context).pushNamed("teacher homepage");
},
child: Text("submit"),
)
],
),
),
);
},
)}}
`
and this is the error thrown in the debug console
`══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following ProviderNotFoundException was thrown building PopUpMarklist(state:
PopUpMarklistState#96199):
Error: Could not find the correct Provider<MarklistBloc> above this BlocConsumer<MarklistBloc,
MarklistState> Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that BlocConsumer<MarklistBloc, MarklistState> is under your
MultiProvider/Provider<MarklistBloc>.
This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>().toString()),
);
}
```
consider using `builder` like so:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context, child) {
// No longer throws
return Text(context.watch<Example>().toString());
}
);
}
```
If none of these solutions work, consider asking for help on StackOverflow:
https://stackoverflow.com/questions/tagged/flutter
The relevant error-causing widget was:
PopUpMarklist
PopUpMarklist:file:///C:/Users/Yosep/OneDrive/Desktop/flutter%20project/sms_demo/test/fillMarklist_test.dart:26:29
When the exception was thrown, this was the stack:
#0 Provider._inheritedElementOf (package:provider/src/provider.dart:343:7)
#1 Provider.of (package:provider/src/provider.dart:293:30)
#2 ReadContext.read (package:provider/src/provider.dart:649:21)
#3 _BlocConsumerState.initState (package:flutter_bloc/src/bloc_consumer.dart:108:36)
#4 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4893:57)
#5 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4729:5)
... Normal element mounting (9 frames)
#14 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3790:14)
#15 Element.updateChild (package:flutter/src/widgets/framework.dart:3524:20)
#16 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1198:16)
#17 RenderObjectToWidgetElement.update (package:flutter/src/widgets/binding.dart:1175:5)
#18 RenderObjectToWidgetElement.performRebuild (package:flutter/src/widgets/binding.dart:1189:7)
#19 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#20 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2659:19)
#21 AutomatedTestWidgetsFlutterBinding.drawFrame (package:flutter_test/src/binding.dart:1128:19)
#22 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5)
#23 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1144:15)
#24 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1081:9)
#25 AutomatedTestWidgetsFlutterBinding.pump.<anonymous closure> (package:flutter_test/src/binding.dart:995:9)
#28 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#29 AutomatedTestWidgetsFlutterBinding.pump (package:flutter_test/src/binding.dart:982:27)
#30 WidgetTester.pumpWidget.<anonymous closure> (package:flutter_test/src/widget_tester.dart:548:22)
#33 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#34 WidgetTester.pumpWidget (package:flutter_test/src/widget_tester.dart:545:27)
#35 main.<anonymous closure> (file:///C:/Users/Yosep/OneDrive/Desktop/flutter%20project/sms_demo/test/fillMarklist_test.dart:26:18)
#36 main.<anonymous closure> (file:///C:/Users/Yosep/OneDrive/Desktop/flutter%20project/sms_demo/test/fillMarklist_test.dart:22:44)
#37 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:170:29)
<asynchronous suspension>
<asynchronous suspension>
(elided 5 frames from dart:async and package:stack_trace)
════════════════════════════════════════════════════════════════════════════════════════════════════
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following StateError was thrown running a test:
Bad state: No element
When the exception was thrown, this was the stack:
#0 Iterable.single (dart:core/iterable.dart:654:25)
#1 WidgetController.state (package:flutter_test/src/controller.dart:156:42)
#2 WidgetTester.showKeyboard.<anonymous closure> (package:flutter_test/src/widget_tester.dart:1042:42)
#3 WidgetTester.showKeyboard.<anonymous closure> (package:flutter_test/src/widget_tester.dart:1041:39)
#6 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#7 WidgetTester.showKeyboard (package:flutter_test/src/widget_tester.dart:1041:27)
#8 WidgetTester.enterText.<anonymous closure> (package:flutter_test/src/widget_tester.dart:1077:13)
#9 WidgetTester.enterText.<anonymous closure> (package:flutter_test/src/widget_tester.dart:1076:39)
#12 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#13 WidgetTester.enterText (package:flutter_test/src/widget_tester.dart:1076:27)
#14 main.<anonymous closure> (file:///C:/Users/Yosep/OneDrive/Desktop/flutter%20project/sms_demo/test/fillMarklist_test.dart:27:18)
<asynchronous suspension>
<asynchronous suspension>
(elided 5 frames from dart:async and package:stack_trace)
The test description was:
invalid input for testtwo
════════════════════════════════════════════════════════════════════════════════════════════════════
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following message was thrown:
Multiple exceptions (2) were detected during the running of the current test, and at least one was
unexpected.
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: invalid input for testtwo
✖ invalid input for testtwo
Exited (1)
`
i used Go router for routing so how do i get resolve this issue thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
欢迎来到社区。
小部件测试用于与应用程序的其他组件隔离测试单个小部件或页面。测试小部件时,请勿测试集团或域层或数据层(为此,我们进行了集成测试)。
因此,您需要模拟该页面所需的集团。您应该看到一些窗口小部件的示例 testing 或更简单的测试。
您缺少嘲笑您需要 oightail and bloc_test 。阅读他们的文档以更好地理解模拟。
我建议您在提出问题之前先查找文章教程,因为它可能会更有益,并帮助您提出正确的问题。您可以进一步阅读有关小部件测试在这里。
welcome to the community.
Widget testing is for testing individual widgets or pages in isolation from other components of the application. When testing a widget do not test bloc or domain layer or data layer(for that we have integration testing).
Hence you need to mock the bloc that are necessary for that page. You should see some examples for widget testing or simpler tests in bloc examples these are some good example repos see their widget tests.
You are missing mocking you will need mocktail and bloc_test. Read their documentation for better understanding on mocks.
I suggest you should look for articles tutorial before asking question as it can be a lot more informative and will help you to ask the right question. You can further read about widget testing here.