testing - Testing shared_preferences on flutter
问题描述
I'm writing a flutter application and I'm having this issue when writing the tests. This method is supposed to write data into TextFields and tap a button which saves this data in SharedPrefs:
testWidgets('Click on login saves the credentials',
(WidgetTester tester) async {
await tester.pumpWidget(MyApp());
await tester.enterText(find.byKey(Key('phoneInput')), 'test');
await tester.enterText(find.byKey(Key('passwordInput')), 'test');
await tester.tap(find.byIcon(Icons.lock));
SharedPreferences prefs = await SharedPreferences.getInstance();
expect(prefs.getString('phone'), 'test');
expect(prefs.getString('password'), 'test');
});
This test will fail getting the SharedPreferences instance with this error:
The following TimeoutException was thrown running a test:
TimeoutException after 0:00:03.500000: The test exceeded the timeout. It may have hung.
Consider using "addTime" to increase the timeout before expensive operations.
Update: Seems that the problem is not actually the timeout because even with 60 seconds the test is not capable of resolving the SharedPreferences instance.
解决方案
你需要模拟getAll
(shared_preferences
参考:https ://pub.dartlang.org/packages/shared_preferences )
这是示例代码:
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/services.dart'; // <-- needed for `MethodChannel`
void main() {
setUpAll(() {
const MethodChannel('plugins.flutter.io/shared_preferences')
.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'getAll') {
return <String, dynamic>{}; // set initial values here if desired
}
return null;
});
});
testWidgets('Click on login saves the credentials',
(WidgetTester tester) async {
await tester.pumpWidget(MyApp());
await tester.enterText(find.byKey(Key('phoneInput')), 'test');
await tester.enterText(find.byKey(Key('passwordInput')), 'test');
await tester.tap(find.byIcon(Icons.lock));
SharedPreferences prefs = await SharedPreferences.getInstance();
expect(prefs.getString('phone'), 'test');
expect(prefs.getString('password'), 'test');
});
}
原答案:
testWidgets('Click on login saves the credentials',
(WidgetTester tester) async {
final AutomatedTestWidgetsFlutterBinding binding = tester.binding;
binding.addTime(const Duration(seconds: 10)); // or longer if needed
await tester.pumpWidget(MyApp());
await tester.enterText(find.byKey(Key('phoneInput')), 'test');
await tester.enterText(find.byKey(Key('passwordInput')), 'test');
await tester.tap(find.byIcon(Icons.lock));
SharedPreferences prefs = await SharedPreferences.getInstance();
expect(prefs.getString('phone'), 'test');
expect(prefs.getString('password'), 'test');
});
推荐阅读
- android - 同时连接到两个具有相同 UUID 的蓝牙设备
- asp.net - 从网页控制 Windows 应用程序
- mysql - nodejs mysql查询标识符'?错误,但连接查询工作
- node.js - 排除虚拟字段
- php - php ubuntu 打开终端
- python - 检查字段是否为空并用 django 中的另一个字段填充它
- laravel - 获取没有直接关系的 Lavavel (5) 数据
- python - Python 3.x -> 使用递归和循环查找字符串中最后出现的字符
- mongodb - 如何使用 mongo-go-driver 从结构转换为文档
- python - 以编程方式创建 pytest 固定装置