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.
You needed to mock getAll
from shared_preferences
(ref: https://pub.dartlang.org/packages/shared_preferences)
Here's the sample code:
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');
});
}
Original answer:
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');
});
You could use the provided mock setMockInitialValues
testWidgets('Click on login saves the credentials',
(WidgetTester tester) async {
await tester.pumpWidget(MyApp());
SharedPreferences.setMockInitialValues(<String, dynamic>{
'flutter.phone': '',
'flutter.password': '',
});
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');
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With