如何测试 BLoC 监听流?

Posted

技术标签:

【中文标题】如何测试 BLoC 监听流?【英文标题】:How to test BLoC listening stream? 【发布时间】:2021-06-27 04:38:58 【问题描述】:

我想测试我的 chat_bloc 文件,它监听了几个流:

class ChatBloc extends Bloc<ChatEvent, ChatState> 
  final ChatRepository chatRepository;

  ChatBloc(
      @required this.chatRepository,)
      : super(ChatLoading()) 

    this.add(ChatScreenStarted());

    _chatSubscription = chatRepository.message.listen((message)  // error points here
      // do smth
    );
  

  StreamSubscription<Message> _chatSubscription;
  //  mapEventToState and others

  

ChatRepository 中的消息获取器:

@override
  Stream<Message> get message async* 
    yield* chatDataSource.messages;
  

用 mockito 模拟 ChatRepository。并尝试像这样进行测试:

class MockChatRepository extends Mock implements ChatRepository 

void main() 
  MockChatsRepository mockChatsRepository;

  ChatBloc chatBloc;

  setUp(() 
    mockChatRepository = MockChatRepository();
    
    chatBloc = ChatBloc(
      chatRepository: mockChatRepository,
    );
  );

  blocTest(
    'sould ...',
    build: () => chatBloc,
    act: (ChatBloc chatBloc) 
      when(mockChatRepository.message)
          .thenReturn(Stream<Message>.fromIterable([tMessageModel]));
      chatBloc.add(ChatScreenStarted());
    ,
    expect: () => [],
  );


给出错误NoSuchMethodError:方法'listen'在null上被调用。

如何存根该流?

【问题讨论】:

【参考方案1】:

我应该在实例化 bloc 之前这样做:

    when(mockChatRepository.message).thenAnswer((_) 
      return Stream.fromIterable([tMessage]);
    );

这将创建 bloc 已经在监听的流。

附:谢谢 Aleksander "TAZ" Krinzhovnik

【讨论】:

以上是关于如何测试 BLoC 监听流?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 从其他 Bloc 监听 Bloc 状态

BLoC:多次调用监听回调

如何创建一个可以通过访问 MaterialApp 上下文来监听所有页面的 BlocListener?

Bloc:如何模拟获取状态

使用Provider for DI时如何根据Firebase Auth流修改Flutter Firebase Stream监听器?

StreamBuilder 监听流和普通监听方法的区别