[英]Flutter bloc: how to test bloc constructor while mocking event calls?
我想测试由我的构造函数初始化的计时器是否有效地调用了特定的 bloc 事件。
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';
class ExampleBloc extends Bloc<ExampleEvent, ExampleState> {
ExampleBloc() : super(ExampleInitial()) {
on<ExampleEvent>((event, emit) {});
periodicTimer = Timer.periodic(Duration(minutes: 1), (timer) async {
add(ExampleEvent());
});
}
late Timer periodicTimer;
@override
Future<void> close() {
periodicTimer.cancel();
return super.close();
}
}
@immutable
class ExampleEvent {}
@immutable
abstract class ExampleState {}
class ExampleInitial extends ExampleState {}
为了测试它,我考虑过使用小部件测试,因为可以tester.pump()
来自计时器的持续时间。
import 'dart:async';
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:indaband/example_bloc.dart';
import 'package:mocktail/mocktail.dart';
class ExampleBlocMock extends MockBloc<ExampleEvent, ExampleState>
implements ExampleBloc {}
void registerFallbackValues() {
registerFallbackValue<ExampleState>(ExampleInitial());
registerFallbackValue<ExampleEvent>(ExampleEvent());
}
void main() {
setUpAll(() {
registerFallbackValues();
});
group(
'Test',
() {
final bloc = ExampleBlocMock();
final blocStateController = StreamController<ExampleState>.broadcast();
when(() => bloc.stream).thenAnswer((_) => blocStateController.stream);
testWidgets('test periodic timer', (WidgetTester tester) async {
final bloc = ExampleBloc();
final widget = BlocProvider(
create: (context) => bloc,
child: Container(),
);
await tester.pumpWidget(widget);
await tester.pump(Duration(minutes: 1));
verify(() => bloc.add(ExampleEvent())).called(1);
await tester.pump(Duration(minutes: 1));
verify(() => bloc.add(ExampleEvent())).called(2);
await tester.pump(Duration(minutes: 1));
verify(() => bloc.add(ExampleEvent())).called(3);
});
},
);
}
我不知道是否可以只模拟.add(...)
调用,以使计时器可用。
这里有一些问题:
您在测试中创建了一个模拟块,并且它根本没有被使用或验证,因为您正在创建一个具有相同名称的“真实”块。
您的ExampleEvent
不会在每个计时器滴答声上发出新的 state,因此无需测试或捕获任何内容。
测试 bloc 本身是一个单元测试,而不是小部件测试。 bloc_test
package 提供了一组方便的实用程序来对块进行单元测试,请阅读文档。
Bloc 事件/状态必须实现相等覆盖,以确保在每个事件之后发出新的 state,请参阅 bloc 文档和深入教程,了解 bloc package 如何工作。
解决上述问题后,您可以添加测试用例来验证发出的 state 是否符合您的期望。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.