注意:在正常的应用程序运行中一切正常,问题仅在运行集成测试时发生。
我们使用的是 Flutter Channel 稳定版 2.2.3,对于集成测试,我们使用的是来自 Flutter SDK 的版本:“integration_test: sdk:flutter”</p>
在通过 Screen#1 的 dispose() 方法从 Screen#1 导航到 Screen#2Navigator.of(context).pushNamed(ScreenTwo, arguments: counterProvider);
后,将被调用。我们使用 Provider 进行状态管理,Provider 在 Screen#1 上创建并传递给 Screen#2。现在显示以下错误:
错误:处理后使用了 CounterProvider。一旦在 CounterProvider 上调用了 dispose(),就不能再使用它。
这是因为 Screen#1 页面在导航到 Screen#2 页面后被处理。
有没有人遇到过这个问题,或者有没有人知道我们如何防止在导航后调用处置的方法?</p>
它只发生在集成测试期间。
项目链接:https ://bitbucket.org/UrimGashiABC/test-dispose-issuesample/src/master/
屏幕#1 类:
class ScreenOnePage extends StatefulWidget {
@override
_ScreenOnePageState createState() => _ScreenOnePageState();
}
class _ScreenOnePageState extends State<ScreenOnePage> {
@override
Widget build(BuildContext context) {
CounterProvider counterProvider = Provider.of<CounterProvider>(
context,
listen: true,
);
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Screen #1',
),
SizedBox(
height: 150,
),
Text(
'${counterProvider.counter}',
style: Theme.of(context).textTheme.headline4,
),
SizedBox(
height: 150,
),
TextButton(
key: const Key('screen_one_text_button'),
onPressed: () {
Navigator.of(context).pushNamed(ScreenTwo, arguments: counterProvider);
},
child: Text('Go to screen#2'),
),
],
),
),
floatingActionButton: FloatingActionButton(
key: const Key('screen_one_floating_button'),
onPressed: () => counterProvider.increaseCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
), //
);
}
}
屏幕#2 类:
class ScreenTwoPage extends StatefulWidget {
@override
_ScreenTwoPageState createState() => _ScreenTwoPageState();
}
class _ScreenTwoPageState extends State<ScreenTwoPage> {
@override
Widget build(BuildContext context) {
CounterProvider counterProvider = Provider.of<CounterProvider>(
context,
listen: false,
);
return Scaffold(
appBar: AppBar(),
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'Screen #2',
key: const Key('screen_two_title'),
),
SizedBox(
height: 150,
),
Text(
'Counter: ${counterProvider.counter}',
key: const Key('screen_two_counter'),
),
],
),
),
),
);
}
}
提供者类:
class CounterProvider extends ChangeNotifier{
int counter = 0;
void increaseCounter(){
counter++;
notifyListeners();
}
}
测试类:
void main(){
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('counter test', (WidgetTester tester) async {
app.main();
await tester.pumpAndSettle();
final Finder screenOneButton = find.byKey(const Key('screen_one_text_button'));
final Finder screenOneFloatingButton = find.byKey(const Key('screen_one_floating_button'));
final Finder screenTwoTitle = find.byKey(const Key('screen_two_title'));
final Finder screenTwoCounter = find.byKey(const Key('screen_two_counter'));
await tester.tap(screenOneFloatingButton);
await tester.tap(screenOneButton);
await tester.pumpAndSettle();
expect(screenTwoTitle, findsOneWidget);
});
}