我如何测试颤抖的bloclistener导航并呈现一个初始欢迎页面
我试图测试我的应用程序首次运行并且尚未发生身份验证时发现一个欢迎页面小部件。
无论我尝试什么,我都无法验证小部件是否会呈现。
测试每次都失败。我正在使用期望(find.bytype(欢迎页),findsonewidget);
错误:
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: exactly one matching node in the widget tree
Actual: _WidgetTypeFinder:<zero widgets with type "WelcomePage" (ignoring offstage widgets)>
Which: means none were found but one was expected
测试代码:
class MockAuthenticationBloc
extends MockBloc<AuthenticationEvent, AuthenticationState>
implements AuthenticationBloc {}
void main() {
group('App', () {
late AuthenticationBloc authenticationBloc;
setUp(() {
authenticationBloc = MockAuthenticationBloc();
});
group('Unauthenticated', () {
testWidgets('displays the WelcomeScreen', (tester) async {
when(() => authenticationBloc.state)
.thenReturn(const AuthenticationState.unauthenticated());
await tester.pumpApp(
Scaffold(
body: BlocProvider.value(
value: authenticationBloc,
child: const AppView(),
),
),
);
expect(find.byType(WelcomePage), findsOneWidget);
});
});
});
}
app.dart
class App extends StatelessWidget {
const App({
Key? key,
required this.authenticationRepository,
required this.userRepository,
}) : super(key: key);
final AuthenticationRepository authenticationRepository;
final UserRepository userRepository;
@override
Widget build(BuildContext context) {
return RepositoryProvider.value(
value: authenticationRepository,
child: BlocProvider(
create: (_) => AuthenticationBloc(
authenticationRepository: authenticationRepository,
userRepository: userRepository,
),
child: const AppView(),
),
);
}
}
class AppView extends StatefulWidget {
const AppView({Key? key}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_AppViewState createState() => _AppViewState();
}
class _AppViewState extends State<AppView> {
final _navigatorKey = GlobalKey<NavigatorState>();
NavigatorState get _navigator => _navigatorKey.currentState!;
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: _navigatorKey,
theme: ThemeData(
appBarTheme:
const AppBarTheme(color: Color.fromARGB(255, 214, 39, 185)),
colorScheme: ColorScheme.fromSwatch(
accentColor: const Color.fromARGB(255, 241, 136, 255),
),
),
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: AppLocalizations.supportedLocales,
builder: (context, child) {
return BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
switch (state.status) {
case AuthenticationStatus.authenticated:
_navigator.pushAndRemoveUntil<void>(
HomePage.route(),
(route) => false,
);
break;
case AuthenticationStatus.unauthenticated:
_navigator.pushAndRemoveUntil<void>(
WelcomePage.route(),
(route) => false,
);
break;
case AuthenticationStatus.unknown:
break;
}
},
child: child,
);
},
onGenerateRoute: (_) => SplashPage.route(),
);
}
}
I am trying to test that a WelcomePage widget is found when my App is first run and no authentication has yet happened.
No matter what I try, I cannot verify that the widget gets rendered.
The test fails every time. I am using expect(find.byType(WelcomePage), findsOneWidget);
Error:
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: exactly one matching node in the widget tree
Actual: _WidgetTypeFinder:<zero widgets with type "WelcomePage" (ignoring offstage widgets)>
Which: means none were found but one was expected
Test Code:
class MockAuthenticationBloc
extends MockBloc<AuthenticationEvent, AuthenticationState>
implements AuthenticationBloc {}
void main() {
group('App', () {
late AuthenticationBloc authenticationBloc;
setUp(() {
authenticationBloc = MockAuthenticationBloc();
});
group('Unauthenticated', () {
testWidgets('displays the WelcomeScreen', (tester) async {
when(() => authenticationBloc.state)
.thenReturn(const AuthenticationState.unauthenticated());
await tester.pumpApp(
Scaffold(
body: BlocProvider.value(
value: authenticationBloc,
child: const AppView(),
),
),
);
expect(find.byType(WelcomePage), findsOneWidget);
});
});
});
}
app.dart
class App extends StatelessWidget {
const App({
Key? key,
required this.authenticationRepository,
required this.userRepository,
}) : super(key: key);
final AuthenticationRepository authenticationRepository;
final UserRepository userRepository;
@override
Widget build(BuildContext context) {
return RepositoryProvider.value(
value: authenticationRepository,
child: BlocProvider(
create: (_) => AuthenticationBloc(
authenticationRepository: authenticationRepository,
userRepository: userRepository,
),
child: const AppView(),
),
);
}
}
class AppView extends StatefulWidget {
const AppView({Key? key}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_AppViewState createState() => _AppViewState();
}
class _AppViewState extends State<AppView> {
final _navigatorKey = GlobalKey<NavigatorState>();
NavigatorState get _navigator => _navigatorKey.currentState!;
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: _navigatorKey,
theme: ThemeData(
appBarTheme:
const AppBarTheme(color: Color.fromARGB(255, 214, 39, 185)),
colorScheme: ColorScheme.fromSwatch(
accentColor: const Color.fromARGB(255, 241, 136, 255),
),
),
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: AppLocalizations.supportedLocales,
builder: (context, child) {
return BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
switch (state.status) {
case AuthenticationStatus.authenticated:
_navigator.pushAndRemoveUntil<void>(
HomePage.route(),
(route) => false,
);
break;
case AuthenticationStatus.unauthenticated:
_navigator.pushAndRemoveUntil<void>(
WelcomePage.route(),
(route) => false,
);
break;
case AuthenticationStatus.unknown:
break;
}
},
child: child,
);
},
onGenerateRoute: (_) => SplashPage.route(),
);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您必须等待您的小部件构建几帧并安顿下来,因此添加
等待tester.pumpandsettle();
:这样,您让Flutter构建了bloclistener的必要帧来执行并显示适当的页面。
I think you have to wait for your widget to build for a few frames and settle so add
await tester.pumpAndSettle();
:That way you let flutter build the necessary frames for the blocListener to execute and display the appropiate page.