如何测试带有droppable/restartable事件的Flutter Bloc?
解决Flutter Bloc中Droppable转换器的测试问题
要验证droppable()转换器的丢弃逻辑,核心是让第一个事件的处理处于异步耗时状态,这样后续事件进来时才会被转换器拦截丢弃。你的测试失败是因为事件处理是同步的,第一个事件处理完成后才会处理第二个,转换器没机会生效。
步骤1:修改事件处理函数为异步耗时
确保_mapSomeEvent包含异步延迟操作,模拟真实场景中的耗时任务:
class SomeBloc extends Bloc<SomeEvent, SomeState> { SomeBloc() : super(InitialState()) { on<SomeEvent>( _mapSomeEvent, transformer: droppable(), ); } Future<void> _mapSomeEvent(SomeEvent event, Emitter<SomeState> emit) async { // 模拟异步耗时操作,让转换器有机会拦截后续事件 await Future.delayed(const Duration(milliseconds: 50)); if (event is DroppableEvent) { emit(StateFromDroppable()); } else { emit(OtherStateFromSomeEvent()); } } }
步骤2:确保事件类型匹配
droppable()仅对同一事件类型生效,所以DroppableEvent必须是SomeEvent的子类:
abstract class SomeEvent extends Equatable { const SomeEvent(); @override List<Object> get props => []; } class DroppableEvent extends SomeEvent { const DroppableEvent(); }
步骤3:调整测试代码
在act中同步连续添加两个事件,不需要await,确保第二个事件在第一个事件的异步处理过程中被提交:
blocTest<SomeBloc, SomeState>( 'droppable转换器丢弃后续同类型事件,仅触发第一个事件的状态', build: () => SomeBloc(), act: (bloc) { bloc.add(DroppableEvent()); // 立即添加第二个事件,此时第一个事件的处理还在进行中 bloc.add(SomeEvent()); }, expect: () => [ StateFromDroppable(), ], );
这样测试就能符合预期:第一个DroppableEvent的异步处理未完成时,第二个SomeEvent被droppable()转换器丢弃,最终仅触发StateFromDroppable状态。
内容的提问来源于stack exchange,提问作者Ianmcuki
相关产品推荐
相关产品推荐

