简体   繁体   English

如何正确测试 flutter bloc

[英]How to test flutter bloc correctly

Today I tried to add my first test and right away I encauntered problems.今天我尝试添加我的第一个测试,但我马上遇到了问题。 I followed many tutorials and read even more but I can't get to work simple LoginBloc test either usuing flutter_test or bloc_test library.我遵循了许多教程并阅读了更多内容,但我无法使用 flutter_test 或 bloc_test 库进行简单的 LoginBloc 测试。 I had to do something fundamentally wrong but I just can't find it.我不得不做一些根本错误的事情,但我就是找不到。 I assume it has something to do with following line in the stack trace:我认为它与堆栈跟踪中的以下行有关:
The argument type 'Bloc<Event, State>' can't be assigned to the parameter type 'dynamic Function()'.

Here is the whole stack trace:这是整个堆栈跟踪:

/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/bloc_test-8.0.0-nullsafety.0/lib/src/when_listen.dart:52:10: Error: The argument type 'Bloc<Event, State>' can't be assigned to the parameter type 'dynamic Function()'.
 - 'Bloc' is from 'package:bloc/src/bloc.dart' ('/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/bloc-7.0.0-nullsafety.3/lib/src/bloc.dart').
    when(bloc).calls(#state).thenReturn(initialState);
         ^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/bloc_test-8.0.0-nullsafety.0/lib/src/when_listen.dart:52:16: Error: The method 'calls' isn't defined for the class 'When<dynamic>'.
 - 'When' is from 'package:mocktail/src/mocktail.dart' ('/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/mocktail-0.0.2-dev.5/lib/src/mocktail.dart').
Try correcting the name to the name of an existing method, or defining a method named 'calls'.
    when(bloc).calls(#state).thenReturn(initialState);
               ^^^^^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/bloc_test-8.0.0-nullsafety.0/lib/src/when_listen.dart:55:8: Error: The argument type 'Bloc<Event, State>' can't be assigned to the parameter type 'dynamic Function()'.
 - 'Bloc' is from 'package:bloc/src/bloc.dart' ('/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/bloc-7.0.0-nullsafety.3/lib/src/bloc.dart').
  when(bloc).calls(#listen).thenAnswer((invocation) {
       ^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/bloc_test-8.0.0-nullsafety.0/lib/src/when_listen.dart:55:14: Error: The method 'calls' isn't defined for the class 'When<dynamic>'.
 - 'When' is from 'package:mocktail/src/mocktail.dart' ('/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/mocktail-0.0.2-dev.5/lib/src/mocktail.dart').
Try correcting the name to the name of an existing method, or defining a method named 'calls'.
  when(bloc).calls(#listen).thenAnswer((invocation) {
             ^^^^^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/bloc_test-8.0.0-nullsafety.0/lib/src/when_listen.dart:58:14: Error: The argument type 'Bloc<Event, State>' can't be assigned to the parameter type 'dynamic Function()'.
 - 'Bloc' is from 'package:bloc/src/bloc.dart' ('/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/bloc-7.0.0-nullsafety.3/lib/src/bloc.dart').
        when(bloc).calls(#state).thenReturn(state);
             ^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/bloc_test-8.0.0-nullsafety.0/lib/src/when_listen.dart:58:20: Error: The method 'calls' isn't defined for the class 'When<dynamic>'.
 - 'When' is from 'package:mocktail/src/mocktail.dart' ('/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/mocktail-0.0.2-dev.5/lib/src/mocktail.dart').
Try correcting the name to the name of an existing method, or defining a method named 'calls'.
        when(bloc).calls(#state).thenReturn(state);
                   ^^^^^
dart:async/stream_controller.dart 561:44                       _StreamController.addError
dart:async/stream_controller.dart 830:13                       _StreamSinkWrapper.addError
package:stream_channel/src/guarantee_channel.dart 145:14       _GuaranteeSink._addError
package:stream_channel/src/guarantee_channel.dart 136:5        _GuaranteeSink.addError
package:flutter_tools/src/test/flutter_platform.dart 439:27    FlutterPlatform._startTest
===== asynchronous gap ===========================
dart:async/zone.dart 1286:19                                   _CustomZone.registerUnaryCallback
dart:async-patch/async_patch.dart 40:23                        _asyncThenWrapperHelper
package:flutter_tools/src/test/flutter_platform.dart 341:36    FlutterPlatform.loadChannel
package:flutter_tools/src/test/flutter_platform.dart 306:44    FlutterPlatform.load
package:test_core/src/runner/loader.dart 225:38                Loader.loadFile.<fn>
===== asynchronous gap ===========================
dart:async/zone.dart 1286:19                                   _CustomZone.registerUnaryCallback
dart:async-patch/async_patch.dart 40:23                        _asyncThenWrapperHelper
package:test_core/src/runner/loader.dart                       Loader.loadFile.<fn>
package:test_core/src/runner/load_suite.dart 97:31             new LoadSuite.<fn>.<fn>
package:test_core/src/runner/load_suite.dart 96:17             new LoadSuite.<fn>.<fn>
package:test_core/src/runner/load_suite.dart 107:8             new LoadSuite.<fn>
package:test_api/src/backend/invoker.dart 231:15               Invoker.waitForOutstandingCallbacks.<fn>
package:test_api/src/backend/invoker.dart 228:14               Invoker.waitForOutstandingCallbacks.<fn>
dart:async/zone.dart 1354:13                                   _rootRun
dart:async/zone.dart 1258:19                                   _CustomZone.run
dart:async/zone.dart 1788:10                                   _runZoned
dart:async/zone.dart 1710:10                                   runZoned
package:test_api/src/backend/invoker.dart 228:5                Invoker.waitForOutstandingCallbacks
package:test_api/src/backend/invoker.dart 383:17               Invoker._onRun.<fn>.<fn>.<fn>
===== asynchronous gap ===========================
dart:async/zone.dart 1286:19                                   _CustomZone.registerUnaryCallback
dart:async-patch/async_patch.dart 40:23                        _asyncThenWrapperHelper
package:test_api/src/backend/invoker.dart                      Invoker._onRun.<fn>.<fn>.<fn>
dart:async/zone.dart 1354:13                                   _rootRun
dart:async/zone.dart 1258:19                                   _CustomZone.run
dart:async/zone.dart 1788:10                                   _runZoned
dart:async/zone.dart 1710:10                                   runZoned
package:test_api/src/backend/invoker.dart 370:9                Invoker._onRun.<fn>.<fn>
dart:async/zone.dart 1354:13                                   _rootRun
dart:async/zone.dart 1258:19                                   _CustomZone.run
dart:async/zone.dart 1788:10                                   _runZoned
dart:async/zone.dart 1710:10                                   runZoned
package:test_api/src/backend/invoker.dart 150:7                Invoker.guard
package:test_api/src/backend/invoker.dart 413:15               Invoker._guardIfGuarded
package:test_api/src/backend/invoker.dart 369:7                Invoker._onRun.<fn>
package:stack_trace/src/chain.dart 94:24                       Chain.capture.<fn>
dart:async/zone.dart 1354:13                                   _rootRun
dart:async/zone.dart 1258:19                                   _CustomZone.run
dart:async/zone.dart 1788:10                                   _runZoned
dart:async/zone.dart 1710:10                                   runZoned
package:stack_trace/src/chain.dart 92:12                       Chain.capture
package:test_api/src/backend/invoker.dart 368:11               Invoker._onRun
package:test_api/src/backend/live_test_controller.dart 153:11  LiveTestController.run
dart:async/future.dart 198:37                                  new Future.microtask.<fn>
dart:async/zone.dart 1346:47                                   _rootRun
dart:async/zone.dart 1258:19                                   _CustomZone.run
dart:async/zone.dart 1162:7                                    _CustomZone.runGuarded
dart:async/zone.dart 1202:23                                   _CustomZone.bindCallbackGuarded.<fn>
dart:async/zone.dart 1354:13                                   _rootRun
dart:async/zone.dart 1258:19                                   _CustomZone.run
dart:async/zone.dart 1162:7                                    _CustomZone.runGuarded
dart:async/zone.dart 1202:23                                   _CustomZone.bindCallbackGuarded.<fn>
dart:async/schedule_microtask.dart 40:21                       _microtaskLoop
dart:async/schedule_microtask.dart 49:5                        _startMicrotaskLoop
dart:isolate-patch/isolate_patch.dart 120:13                   _runPendingImmediateCallback
dart:isolate-patch/isolate_patch.dart 185:5                    _RawReceivePortImpl._handleMessage

Failed to load "######\test\bloc\login\login_bloc_test.dart":
Compilation failed
Test: ######\test\bloc\login\login_bloc_test.dart
Shell: C:\src\flutter\bin\cache\artifacts\engine\windows-x64\flutter_tester.exe

And here is my login_bloc_test:这是我的 login_bloc_test:

class MockAppRepository extends Mock implements Repository {}

void main() {
  MockAppRepository repository = MockAppRepository();
  setUp(() {
    repository = MockAppRepository();
  });

  group('LoginBloc test', () {
    final user =
        User(1, 'email', 'firstName', 'lastName', 'status', 'username', null);
    
    test('emits LoginLoading & LoginSuccess after successful login', () {
      when(repository.logIn('email', 'password'))
          .thenAnswer((realInvocation) async => user);

      final bloc = LoginBloc(repository);
      bloc.add(LogIn('email', 'password'));

      expectLater(
          bloc,
          emitsInOrder([
            LoginInitial(),
            LoginLoading(),
            LoginSuccess(user),
          ]));
    });

    blocTest<LoginBloc, LoginState>(
      'emits LoginLoading & LoginSuccess after successful login',
      build: () {
        when(repository.logIn('email', 'password'))
            .thenAnswer((realInvocation) async => user);
        return LoginBloc(repository);
      },
      act: (bloc) => bloc.add(LogIn('email', 'password')),
      expect: () => [
        LoginInitial(),
        LoginLoading(),
        LoginSuccess(user),
      ],
    );
  });
}


Alright if anyone is expecting the same issue there is newer bloc_test version which is fixing this issue.好吧,如果有人期待同样的问题,那么有更新的 bloc_test 版本正在解决这个问题。
bloc_test: 8.0.0-nullsafety.5 is what you want. bloc_test: 8.0.0-nullsafety.5 是你想要的。

in the second test would be:在第二个测试中将是:

expect: <LoginState>[
        LoginInitial(),
        LoginLoading(),
        LoginSuccess(user),
      ],

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM