WedX - журнал о программировании и компьютерных науках

Как реализовать тесты виджетов с помощью MockBloc?

Я пытаюсь реализовать тест виджета, чтобы проверить форму входа. Этот тест зависит от блока, над которым я издеваюсь, используя MockBloc. Однако он выдает следующую ошибку:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK╞════════════════════════════════════════════════════
The following StateError was thrown running a test:
Bad state: No method stub was called from within `when()`. Was a real method called, or perhaps an 
extension method?

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

Я также просмотрел следующий файл на gitlub, который является примером проверки виджета с помощью bloc_test. Ссылку можно найти на официальном сайте библиотеки Bloc, в частности, в приложении Todos во Flutter с использованием библиотеки Bloc.

Однако в этом примере используется bloc_test: ^3.0.1, а я использую bloc_test: ^8.0.0, что можно найти здесь.

Вот минимальный пример:

  • Виджет формы входа
class LoginForm extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Form(
      key: '_loginForm',
      child: Column(
        children: <Widget>[
           ...
           BlocConsumer<AuthenticationBloc, AuthenticationState>(
             listener: (context, state) {
               ...
             },
             builder: (context, state) {
               if (state is AuthenticationInitial) {
                 ...
               } else if (state is LoggingIn || state is LoggedIn) {
                 ...
               } else if (state is Error) { 
                 return Column(
                  children: <Widget>[
                    ...
                    Message(
                      message: state.message,
                      messageContainerWidth: 290,
                      messageContainerHeight: 51,
                    ),
                    ...
                  ],
                );
               }
             }
           ),
        ],
      ),
    );
  }
}
  • Виджет сообщений
class Message extends StatelessWidget {
  final String message;
  final double messageContainerWidth;
  final double messageContainerHeight;

  ...
  @override
  Widget build(BuildContext context) {
    return Container(
      width: messageContainerWidth,
      height: messageContainerHeight,
      child: Center(
        child: message != ""
            ? Text(
                message,
                textAlign: TextAlign.center,
                style: TextStyle(
                  color: Color.fromRGBO(242, 241, 240, 1),
                  fontSize: 15,
                ),
              )
            : child,
      ),
    );
  }
}
  • Тест виджета (я хочу проверить, отображается ли сообщение, когда состояние аутентификации равно Error)
...
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
...

// Mocking my LoginUser usecase
class MockLoginUser extends Mock implements LoginUser {}

// Mocking my bloc
class MockAuthenticationBloc
    extends MockBloc<AuthenticationEvent, AuthenticationState>
    implements AuthenticationBloc {}

class AuthenticationStateFake extends Fake implements AuthenticationState {}

void main() {
  MockLoginUser mockLoginUser;

  setUpAll(() {
    registerFallbackValue<AuthenticationState>(AuthenticationStateFake());
  });

  setUp(() {
    mockLoginUser = MockLoginUser();
    authenticationBloc = AuthenticationBloc(loginUser: mockLoginUser);
  });

  group('Login', () {
    testWidgets(
        'should show a Message when the Authentication state is Error',
        (WidgetTester tester) async {
      whenListen(
        authenticationBloc,
        Stream.fromIterable(
          [
            LoggingIn(),
            Error(
              message: 'Some error message',
            ),
          ],
        ),
        initialState: AuthenticationInitial(),
      );
     
      final widget = LoginForm();
      await tester.pumpWidget(
         BlocProvider<AuthenticationBloc>(
          create: (context) => authenticationBloc,
          child: MaterialApp(
            title: 'Widget Test',
            home: Scaffold(body: widget),
          ),
        ),
      );
      await tester.pumpAndSettle();

      final messageWidget = find.byType(Message);
      expect(messageWidget, findsOneWidget);
    });
  });
}

Я буду очень признателен, если кто-нибудь поможет мне решить ошибку или подскажет другой способ реализовать тесты виджетов.

Заранее спасибо!


Ответы:


1

Я решил проблему, я хотел бы поделиться ответом, если кто-то узнает ту же проблему.

Прежде всего, эта ссылка оказалась действительно полезной.

Решение состояло в том, чтобы изменить Проверку виджета следующим образом:

...
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
...

class MockAuthenticationBloc
    extends MockBloc<AuthenticationEvent, AuthenticationState>
    implements AuthenticationBloc {}

class AuthenticationStateFake extends Fake implements AuthenticationState {}

class AuthenticationEventFake extends Fake implements AuthenticationEvent {}

void main() {
  group('Login', () {

    setUpAll(() {
      registerFallbackValue<AuthenticationState>(AuthenticationStateFake());
      registerFallbackValue<AuthenticationEvent>(AuthenticationEventFake());
    });

    testWidgets(
        'should show a Message when the Authentication state is Error',
        (WidgetTester tester) async {
      // arrange
      final mockAuthenticationBloc = MockAuthenticationBloc();
      when(() => mockAuthenticationBloc.state).thenReturn(
        LoggingIn(), // the desired state
      );

      // find
      final widget = LoginForm();
      final messageWidget = find.byType(Message);

      // test
      await tester.pumpWidget(
         BlocProvider<AuthenticationBloc>(
          create: (context) => mockAuthenticationBloc,
          child: MaterialApp(
            title: 'Widget Test',
            home: Scaffold(body: widget),
          ),
        ),
      );
      await tester.pumpAndSettle();

      // expect
      expect(messageWidget, findsOneWidget);
    });
  });
}
23.04.2021
Новые материалы

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

Учебные заметки: создание моего первого пакета Node.js
Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

ИИ в аэрокосмической отрасли
Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


Для любых предложений по сайту: [email protected]