Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 如何使用MockBloc实现小部件测试?_Flutter_Flutter Test_Widget Test Flutter_Bloc Test - Fatal编程技术网

Flutter 如何使用MockBloc实现小部件测试?

Flutter 如何使用MockBloc实现小部件测试?,flutter,flutter-test,widget-test-flutter,bloc-test,Flutter,Flutter Test,Widget Test Flutter,Bloc Test,为了测试登录表单,我正在尝试实现一个小部件测试。这个测试依赖于我正在使用MockBloc模拟的一个bloc。但是,它会引发以下错误: ══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK╞════════════════════════════════════════════════════ The following StateError was thrown running a test: Bad state: No method stub was c

为了测试登录表单,我正在尝试实现一个小部件测试。这个测试依赖于我正在使用MockBloc模拟的一个bloc。但是,它会引发以下错误:

══╡ 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?
我在下面发现了一个类似的错误,但我不认为这能帮助我解决问题

我还研究了以下内容,这是一个使用bloc_测试的小部件测试示例。该链接可以在Bloc图书馆的官方网站上找到,特别是在

但是,该示例使用的是
bloc\u测试:^3.0.1
,而我使用的是
bloc\u测试:^8.0.0
,可以找到

下面是一个简单的例子:

  • LoginForm小部件
  • 小部件测试(我想测试验证状态为Error时是否显示消息)
。。。
导入“包:bloc_测试/bloc_测试.dart”;
进口“包装:颤振团/颤振团.飞镖”;
进口“包装:颤振试验/颤振试验.dart”;
导入“package:mocktail/mocktail.dart”;
...
//嘲笑我的登录用户用例
类MockLoginUser扩展了Mock实现LoginUser{}
//嘲笑我的集团
类MockAuthenticationBloc
扩大模拟集团
实现AuthenticationBloc{}
类AuthenticationStateFake扩展了Fake实现AuthenticationState{}
void main(){
mocklogin用户mocklogin用户;
setUpAll((){
registerFallbackValue(AuthenticationStateFake());
});
设置((){
mockLoginUser=mockLoginUser();
authenticationBloc=authenticationBloc(登录用户:mockLoginUser);
});
组('登录',(){
测试小部件(
'当身份验证状态为错误时应显示消息',
(WidgetTester测试仪)异步{
何时上市(
认证集团,
Stream.fromIterable(
[
登录(),
错误(
消息:“某些错误消息”,
),
],
),
initialState:AuthenticationInitial(),
);
final widget=LoginForm();
等待测试仪.pumpWidget(
BlocProvider(
创建:(上下文)=>authenticationBloc,
孩子:MaterialApp(
标题:“小部件测试”,
主页:脚手架(主体:小部件),
),
),
);
等待测试仪。泵和沉降器();
final messageWidget=find.byType(消息);
expect(messageWidget、findsOneWidget);
});
});
}
如果有人能帮我解决这个错误,或者让我知道实现小部件测试的另一种方法,我将非常感激


提前谢谢

我解决了问题,我想分享答案,以防有人发现同样的问题

首先,这真的很有帮助

解决方案是通过以下方式更改小部件测试:

...
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);
    });
  });
}
。。。
导入“包:bloc_测试/bloc_测试.dart”;
进口“包装:颤振团/颤振团.飞镖”;
进口“包装:颤振试验/颤振试验.dart”;
导入“package:mocktail/mocktail.dart”;
...
类MockAuthenticationBloc
扩大模拟集团
实现AuthenticationBloc{}
类AuthenticationStateFake扩展了Fake实现AuthenticationState{}
类AuthenticationEventFake扩展Fake实现AuthenticationEvent{}
void main(){
组('登录',(){
setUpAll((){
registerFallbackValue(AuthenticationStateFake());
registerFallbackValue(AuthenticationEventFake());
});
测试小部件(
'当身份验证状态为错误时应显示消息',
(WidgetTester测试仪)异步{
//安排
最终mockAuthenticationBloc=mockAuthenticationBloc();
当(()=>mockAuthenticationBloc.state)。然后返回(
LoggingIn(),//所需状态
);
//发现
final widget=LoginForm();
final messageWidget=find.byType(消息);
//试验
等待测试仪.pumpWidget(
BlocProvider(
创建:(上下文)=>mockAuthenticationBloc,
孩子:MaterialApp(
标题:“小部件测试”,
主页:脚手架(主体:小部件),
),
),
);
等待测试仪。泵和沉降器();
//期待
expect(messageWidget、findsOneWidget);
});
});
}

我解决了这个问题,我想分享答案,以防有人发现同样的问题

首先,这真的很有帮助

解决方案是通过以下方式更改小部件测试:

...
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);
    });
  });
}
。。。
导入“包:bloc_测试/bloc_测试.dart”;
进口“包装:颤振团/颤振团.飞镖”;
进口“包装:颤振试验/颤振试验.dart”;
导入“package:mocktail/mocktail.dart”;
...
类MockAuthenticationBloc
扩大模拟集团
实现AuthenticationBloc{}
类AuthenticationStateFake扩展了Fake实现AuthenticationState{}
类AuthenticationEventFake扩展Fake实现AuthenticationEvent{}
void main(){
组('登录',(){
setUpAll((){
registerFallbackValue(AuthenticationStateFake());
registerFallbackValue(AuthenticationEventFake());
});
测试小部件(
'当身份验证状态为错误时应显示消息',
(WidgetTester测试仪)异步{
//安排
最终mockAuthenticationBloc=mockAuthenticationBloc();
当(()=>mockAuthenticationBloc.state)。然后返回(
LoggingIn(),//所需状态
);
//发现
final widget=LoginForm();
final messageWidget=find.byType(消息);
//试验
等待测试仪.pumpWidget(
BlocProvider(
创建:(上下文)=>mockAuthenticationBloc,
孩子:MaterialApp(
标题:“小部件测试”,
主页:脚手架(主体:小部件),
),
),
);
等待测试仪。泵和沉降器();
//期待
expect(messageWidget、findsOneWidget);
});
});
}
...
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);
    });
  });
}
...
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);
    });
  });
}