Flutter pushReplacementNamed未通过测试



我有两个屏幕(登录和注册(,它们分别有相互链接的按钮。对于登录页面,一个按钮触发pushReplacementNamed导航到注册页面。类似地,在注册页面中,一个不同的按钮触发pushReplacementNamed导航到登录页面。

login_screen.dart:

SecondaryButton(
onPressed: () {
Navigator.pushReplacementNamed(context, SignupScreen.id);
},
key: LoginScreen.signupBtnKey,
child: Text('Sign Up'),
),

signup_screen.dart:

SecondaryButton(
onPressed: () {
Navigator.pushReplacementNamed(context, LoginScreen.id);
},
key: SignupScreen.loginBtnKey,
child: Text('Log In'),
)

当在模拟器上测试时,这两个按钮似乎都能正常工作,但当尝试运行自动测试时,它不适用于注册屏幕。

login_screen_test.dart

class MockNavigatorObserver extends Mock implements NavigatorObserver {}
void main() {
group('Login Screen Widget Tests', () {
NavigatorObserver mockObserver;
setUp(() {
mockObserver = MockNavigatorObserver();
});
Widget createLoginScreen() {
return MaterialApp(
initialRoute: LoginScreen.id,
routes: {
LoginScreen.id: (context) => LoginScreen(),
SignupScreen.id: (context) => SignupScreen(),
},
navigatorObservers: [mockObserver],
);
}
testWidgets(
'Testing if sign up button shows up and triggers navigation after tapped',
(tester) async {
await tester.pumpWidget(createLoginScreen());
expect(find.byKey(LoginScreen.signupBtnKey), findsOneWidget);
await tester.tap(find.byKey(LoginScreen.signupBtnKey));
await tester.pumpAndSettle();
verify(
mockObserver.didReplace(
oldRoute: anyNamed('oldRoute'),
newRoute: anyNamed('newRoute'),
),
);
expect(find.byType(SignupScreen), findsOneWidget);
expect(find.byType(LoginScreen), findsNothing);
},
);
});
}

signup_screen_test.dart

class MockNavigatorObserver extends Mock implements NavigatorObserver {}
void main() {
group('Signup Screen Widget Tests', () {
NavigatorObserver mockObserver;
setUp(() {
mockObserver = MockNavigatorObserver();
});
Widget createSignupScreen() {
return MaterialApp(
initialRoute: SignupScreen.id,
routes: {
LoginScreen.id: (context) => LoginScreen(),
SignupScreen.id: (context) => SignupScreen(),
},
navigatorObservers: [mockObserver],
);
}
testWidgets(
'Testing if log in button shows up and triggers navigation after tapped',
(tester) async {
await tester.pumpWidget(createSignupScreen());
expect(find.byKey(SignupScreen.loginBtnKey), findsOneWidget);
await tester.tap(find.byKey(SignupScreen.loginBtnKey));
await tester.pumpAndSettle();
verify(
mockObserver.didReplace(
oldRoute: anyNamed('oldRoute'),
newRoute: anyNamed('newRoute'),
),
);
expect(find.byType(LoginScreen), findsOneWidget);
expect(find.byType(SignupScreen), findsNothing);
},
);
});
}

此操作失败,出现以下异常:

The following TestFailure object was thrown running a test:
No matching calls. All calls: MockNavigatorObserver.navigator,
MockNavigatorObserver._navigator==NavigatorState#03a3a(tickers: tracking 1 ticker),
MockNavigatorObserver.didPush(MaterialPageRoute<dynamic>(RouteSettings("/signup", null), animation:
AnimationController#9b7dc(⏭ 1.000; paused; for MaterialPageRoute<dynamic>(/signup))), null)

这表明didReplace((方法没有被触发。每一页的代码几乎都是相同的,所以我不明白为什么一页通过了,另一页失败了。

如果有任何见解,我将不胜感激!

页面早期的其他文本字段将其从屏幕上删除。需要添加tester.fling()

最新更新