8
votes

Test de shared_preferences sur le flutter

J'écris une application Flutter et j'ai ce problème lors de l'écriture des tests. Cette méthode est censée écrire des données dans TextFields et appuyer sur un bouton qui enregistre ces données dans SharedPrefs:

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.

Ce test échouera à obtenir l'instance SharedPreferences avec cette erreur:

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');
  });

Mise à jour: Il semble que le problème ne soit pas réellement le délai d'expiration car même avec 60 secondes, le test n'est pas capable de résoudre l'instance SharedPreferences.


0 commentaires

3 Réponses :


0
votes

Comme mentionné sur github, vous pouvez faire quelque chose comme ceci au début de votre test:

testWidgets('MyWidget', (WidgetTester tester) async {
  final AutomatedTestWidgetsFlutterBinding binding = tester.binding;
  binding.addTime(const Duration(seconds: 10)); // or longer if needed
  await tester.pumpWidget(new MyWidget());
  await tester.tap(find.text('Save'));
  expect(find.text('Success'), findsOneWidget);
});

Voici le lien et l'exemple complet: https://github.com/flutter/flutter/issues/19175 p >

tester.addTime(const Duration(seconds: 10));


2 commentaires

Je ne trouve aucune méthode addTime sur WidgetTester


Auteur original de cet "exemple de code" ici, ce code ne fonctionne que lorsque le PR est fusionné



4
votes

Vous deviez vous moquer de getAll de shared_preferences (ref: https://pub.dartlang.org/packages/shared_preferences )

Voici l'exemple de code:

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');
  });

Réponse originale:

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');
  });
}



3 commentaires

Semble que le problème n'est pas réellement le délai d'expiration car même avec 60 secondes, le test n'est pas capable de résoudre l'instance SharedPreferences. Merci pour l'exemple de durée en tout cas, c'est vraiment clarifiant. J'espère que votre PR sera bientôt fusionné.


Je mets à jour la réponse, vous deviez vous moquer de getAll de shared_preferences


Cette solution ne semble pas viable, car l'importation de 'package: flutter / services.dart' provoque le problème dart: ui ( github.com/flutter/flutter/issues/27826 )



0
votes

Vous pouvez utiliser la maquette fournie 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');
  });


2 commentaires

Dans mon problème, ce que je voulais tester, c'est si les préférences ont été modifiées avec les bonnes valeurs lorsque j'ai cliqué sur un bouton. Si j'initialise les préférences avec cette valeur, le test n'ajouterait aucune valeur puisque je corrige le résultat.


dans ce cas, vous essayez de définir la valeur initiale sur une chaîne vide.