Ширина флаттера Риверподов не превышает прошлого состояния загрузки

#flutter #riverpod #widget-test-flutter

Вопрос:

ОБНОВЛЕНИЕ: Переписал тест так же, как я тестирую другой потребительский виджет, который действительно работает, но он все еще не работает для моего теста, и я не могу понять, почему 🙁 Текущий подход:

 
void main() {
  final List<Exercise> _mockExercises = [
    Exercise(
        userID: 'uid123',
        title: 'Übung1',
        repetitions: 10,
        isCompleted: false,
        isVideo: false,
        unit: 'Sekunden',
        description: 'Some description',
        exerciseID: '42',
        imageUrl: 'https://via.placeholder.com/150',
        thumbUrl: 'https://via.placeholder.com/150'),
    Exercise(
        userID: 'uid123',
        title: 'Übung2',
        repetitions: 20,
        isCompleted: false,
        isVideo: false,
        unit: 'Sekunden',
        description: 'Some description2',
        exerciseID: '43',
        imageUrl: 'https://via.placeholder.com/150',
        thumbUrl: 'https://via.placeholder.com/150'),
  ];

  testWidgets('user exercise list - pump', (WidgetTester tester) async {
    await mockNetworkImagesFor(() async {
      await tester.pumpWidget(ProviderScope(
        child: MyApp(),

        /// overrides: provide fake asyncvalue data to stream
        overrides: [
          exerciseCollectionStream
              .overrideWithValue(AsyncValue.data(_mockExercises))
        ],
      ));

      await tester.pump();
      // The first frame is a loading state.
      expect(find.byType(Loading), findsOneWidget);

      await tester.pumpAndSettle();
      // await Future.delayed(Duration(seconds: 2));
      // await tester.pumpAndSettle();

      // No-longer loading
      expect(find.byType(Loading), findsNothing);
    });
  });
}
 

Я пытаюсь написать тест виджета для виджета Listview, и я никогда не перехожу в состояние загрузки «Asyncvalue».когда состояние в моем тесте и оно застряло в загрузке.

Я попытался подойти к тесту, как в документах Riverpod, или как описано здесь: https://codewithandrea.com/videos/flutter-state-management-riverpod/

Но я застрял :-/ У нас есть виджет загрузки (), который мы тестируем, чтобы увидеть, исчезнет ли он, но это не так..

Это код теста:

 
class ExerciseRepo {
  // ignore: missing_return
  Future<List<Exercise>> exerciseList() {
// should get data from database
  }
}

final exerciseRepoProvider = Provider((ref) => ExerciseRepo());

final exerciseListProvider = FutureProvider<List<Exercise>>((ref) {
  final repo = ref.watch(exerciseRepoProvider);
  return repo.exerciseList();
});

class MockExercisesRepository extends Mock implements ExerciseRepo {
  @override
  Future<List<Exercise>> exerciseList() {
    return Future.value([
      Exercise(
          title: 'Übung1',
          repetitions: 10,
          isCompleted: false,
          isVideo: false,
          unit: 'Sekunden',
          description: 'Some description',
          exerciseID: '42',
          imageUrl: 'https://via.placeholder.com/150',
          thumbUrl: 'https://via.placeholder.com/150'),
      Exercise(
          title: 'Übung2',
          repetitions: 20,
          isCompleted: false,
          isVideo: false,
          unit: 'Sekunden',
          description: 'Some description2',
          exerciseID: '43',
          imageUrl: 'https://via.placeholder.com/150',
          thumbUrl: 'https://via.placeholder.com/150'),
    ]);
  }
}

void main() {
  testWidgets('override repositoryProvider', (WidgetTester tester) async {
    await mockNetworkImagesFor(() async {
      await tester.pumpWidget(
        ProviderScope(
          overrides: [
            exerciseListProvider.overrideWithProvider(
                Provider((ref) => MockExercisesRepository))
          ],
          child: MaterialApp(
            home: Builder(builder: (context) {
              return UserExerciseList();
            }),
          ),
        ),
      );
      // The first frame is a loading state.
      expect(find.byType(Loading), findsOneWidget);

      await tester.pump();
      await tester.pumpAndSettle();
      // await Future.delayed(Duration(seconds: 3));
      await tester.pumpAndSettle();

      // No-longer loading
      expect(find.byType(Loading), findsNothing);
    });
  });
}


 

The error message is:

 The following TestFailure object was thrown running a test:
  Expected: no matching nodes in the widget tree
  Actual: _WidgetTypeFinder:<exactly one widget with type "Loading" (ignoring offstage widgets):
Loading>
   Which: means one was found but none were expected

When the exception was thrown, this was the stack:
#4      main.<anonymous closure>.<anonymous closure> (file:///.../test/widget_exercise_list_test.dart:77:7)
<asynchronous suspension>
#5      main.<anonymous closure>.<anonymous closure> (file:///.../test/widget_exercise_list_test.dart)
#10     HttpOverrides.runZoned (dart:_http/overrides.dart:55:26)
#11     mockNetworkImagesFor (package:network_image_mock/src/network_image_mock.dart:9:24)
#12     main.<anonymous closure> (file:///.../test/widget_exercise_list_test.dart:54:11)
#13     testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:146:29)
<asynchronous suspension>
#14     testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart)
#15     TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:784:19)
<asynchronous suspension>
#18     TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:764:14)
#19     AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1173:24)
#20     FakeAsync.run.<anonymous closure>.<anonymous closure> (package:fake_async/fake_async.dart:178:54)
#25     withClock (package:clock/src/default.dart:48:10)
#26     FakeAsync.run.<anonymous closure> (package:fake_async/fake_async.dart:178:22)
#31     FakeAsync.run (package:fake_async/fake_async.dart:178:7)
#32     AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:1170:15)
#33     testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:138:24)
#34     Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:175:19)
<asynchronous suspension>
#35     Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart)
#40     Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:173:13)
#41     Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:231:15)
#46     Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:228:5)
#47     Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:383:17)
<asynchronous suspension>
#48     Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart)
#53     Invoker._onRun.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:370:9)
#54     Invoker._guardIfGuarded (package:test_api/src/backend/invoker.dart:415:15)
#55     Invoker._onRun.<anonymous closure> (package:test_api/src/backend/invoker.dart:369:7)
#62     Invoker._onRun (package:test_api/src/backend/invoker.dart:368:11)
#63     LiveTestController.run (package:test_api/src/backend/live_test_controller.dart:153:11)
#64     RemoteListener._runLiveTest.<anonymous closure> (package:test_api/src/remote_listener.dart:256:16)
#69     RemoteListener._runLiveTest (package:test_api/src/remote_listener.dart:255:5)
#70     RemoteListener._serializeTest.<anonymous closure> (package:test_api/src/remote_listener.dart:208:7)
#88     _GuaranteeSink.add (package:stream_channel/src/guarantee_channel.dart:125:12)
#89     new _MultiChannel.<anonymous closure> (package:stream_channel/src/multi_channel.dart:159:31)
#93     CastStreamSubscription._onData (dart:_internal/async_cast.dart:85:11)
#127    new _WebSocketImpl._fromSocket.<anonymous closure> (dart:_http/websocket_impl.dart:1145:21)
#135    _WebSocketProtocolTransformer._messageFrameEnd (dart:_http/websocket_impl.dart:338:23)
#136    _WebSocketProtocolTransformer.add (dart:_http/websocket_impl.dart:232:46)
#146    _Socket._onData (dart:io-patch/socket_patch.dart:2044:41)
#155    new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1580:33)
#156    _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1076:14)
(elided 115 frames from dart:async and package:stack_trace)

This was caught by the test expectation on the following line:
  file:///.../test/widget_exercise_list_test.dart line 77
The test description was:
  override repositoryProvider
════════════════════════════════════════════════════════════════════════════════════════════════════

Test failed. See exception logs above.
The test description was: override repositoryProvider
 

Это соответствующая часть UserExerciseList()

 @override
  Widget build(BuildContext context, ScopedReader watch) {
    AsyncValue<List<Exercise>> userExercisesList =
        watch(exerciseCollectionStream);

    return userExercisesList.when(
        error: (error, stack) => ErrorInfo(error, stack),
        loading: () => Loading(),
        data: (List<Exercise> exercises) {
 

Я также заменил Future на stream в своих тестах, тоже не сработало :-/ Любая помощь высоко ценится!

Большое спасибо!

Комментарии:

1. Любая возможная помощь..? Вероятно, публикация в день flutter engage была не слишком многообещающей, так как в настоящее время всем очень любопытно 🙂

2. вы пробовали добавить ожидание будущего? задерживается в вашем издевательском списке упражнений ?

3. Спасибо за идею, к сожалению, она не работает 🙁

4. Я также переписал весь тест на более простую версию, которая на самом деле отлично работает аналогично другому тесту виджета, но этот конкретный тест все равно не проходит, и тест все равно проваливается.

5. У кого-нибудь еще есть идея? Все еще борется 🙁

Ответ №1:

Мне пришлось попробовать использовать несколько pump s, чтобы получить мои фиктивные данные для возврата и изменения состояния.

 await tester.pumpWidget(ProviderScope(child: const MyApp()));

await tester.pump(Duration(seconds: 1));
await tester.pump(Duration(seconds: 1));
await tester.pump(Duration(seconds: 1));

expect(find.text("Sample Text"), findsOneWidget);
 

pumpAndSettle не получилось.