Karthikn
Karthikn

Reputation: 85

LateInitializationError: Field '_prefs@29023595' has not been initialized in flutter testing

void main() async {

  WidgetsFlutterBinding.ensureInitialized();
  await SharedPreferenceHelper.initPreference();
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ThemeProvider(),),
        ChangeNotifierProvider(create: (_) => ApiProvider(),),
      ],
      child: const MyApp()
    )
  );
  
}

This is my main.dart file I used two Providers for Theme of the app and API calling.I used SharedPreference as Singleton class to avoid multiple instance creation.

class SharedPreferenceHelper {
  static late SharedPreferences _prefs;

  static Future<void> initPreference() async {
    _prefs = await SharedPreferences.getInstance();
  }

  static SharedPreferences getInstance() => _prefs;
}

But I have an issue while I testing it this is my testing code and assume in the sign in screen with textfield that only accept 10 numbers as input (only number).

  testWidgets("Validate Signin field with different input", (WidgetTester tester) async {
    

    // tester.view.devicePixelRatio = 1.0;
     await tester.pumpWidget(
      MultiProvider(
        providers: [
            ChangeNotifierProvider(create: (_) => ThemeProvider()),
            ChangeNotifierProvider(create: (_) => ApiProvider()),
          ],
        child: const MaterialApp(
          home: SigninScreen(),
         )
        )
      );
      // print("Before entering text");
    // Enter invalid text 
    await tester.enterText(find.byKey(const Key("mobile_field")), "123343");
      // print("After entering text");
    // Press the button
    await tester.tap(find.byType(ButtonWidget));
    await tester.pumpAndSettle();

    expect(find.text("Enter a valid user ID"), findsOneWidget);

    // Clear the text field
    await tester.enterText(find.byKey(const Key("mobile_field")), "");
    await tester.pump();

    // Check with the empty String
    await tester.enterText(find.byKey(const Key("mobile_field")), "");
    await tester.tap(find.byType(ButtonWidget));
    await tester.pump();

    expect(find.text("User ID is required"), findsOneWidget);
    
    // Clear the text field
    await tester.enterText(find.byKey(const Key("mobile_field")), "");
    await tester.pump();

    await tester.enterText(find.byKey(const Key("mobile_field")), "9876543210");
    await tester.tap(find.byType(ButtonWidget));
    await tester.pump();

    expect(find.byKey(const Key("home_screen")), findsOneWidget);

  });

but it shows this error from my API Provider

class ApiProvider extends ChangeNotifier{
  // instance of shared preference
  final SharedPreferences _prefs = SharedPreferenceHelper.getInstance();
}

The following LateError was thrown building Consumer<ApiProvider>(dirty, dependencies:
[_InheritedProviderScope<ApiProvider?>]):
LateInitializationError: Field '_prefs@29023595' has not been initialized.

The relevant error-causing widget was:
  Consumer<ApiProvider> Consumer:file:///D:/Projects/kitafeedback/lib/screens/home_screen.dart:43:13

When the exception was thrown, this was the stack:
#0      SharedPreferenceHelper._prefs (package:kitafeedback/common/shared_preference_helper.dart)
#1      SharedPreferenceHelper.getInstance (package:kitafeedback/common/shared_preference_helper.dart:10:45)
#2      new ApiProvider (package:kitafeedback/API/api_provider.dart:18:59)

Upvotes: 1

Views: 28

Answers (1)

Alaindeseine
Alaindeseine

Reputation: 4493

Try to avoid late vars as possible. Use late vars only when your are shure var will be initialised before used or before disposed.

Instead of late var you can use a nullable var

instead of:

class SharedPreferenceHelper {
  static late SharedPreferences _prefs;

use:

class SharedPreferenceHelper {
  static SharedPreferences? _prefs;

and when you need to use _prefs do:

if (_prefs == null) {
  _prefs = await SharedPreferences.getInstance();
}

Just be shure to check if _prefs is null everywhere it can be necessary.

Upvotes: 1

Related Questions