我试图遵循这个问题的答案,但我无法让它发挥作用。
我在柜台应用程序上重现了我的问题,并将其更改如下。
main.dart
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (BuildContext ctx) => DummyCubit(),
),
],
child: MaterialApp(
...
}
class _MyHomePageState extends State<MyHomePage> {
...
@override
Widget build(BuildContext context) {
return Scaffold(
...
body: Center(
child: CounterViewer(counter: _counter),
),
...
);
}
}
class CounterViewer extends StatelessWidget {
const CounterViewer({required this.counter, Key? key}) : super(key: key);
final int counter;
@override
Widget build(BuildContext context) {
return BlocBuilder<DummyCubit, AState>(
builder: (ctx, state) => (state is! StateLoaded)
? const CircularProgressIndicator()
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
);
}
}
dummy_cubit.dart
import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';
class DummyCubit extends Cubit<AState> {
DummyCubit() : super(const InitState());
Future<void> executeLogic() async {
emit(const StateLoading());
// do some logic
emit(StateLoaded('some data'));
}
}
@immutable
abstract class AState {
const AState();
}
class InitState extends AState {
const InitState();
}
class StateLoading extends AState {
const StateLoading();
}
class StateLoaded extends AState {
const StateLoaded(this.data);
final String data;
@override
String toString() => data.toString();
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is StateLoaded &&
runtimeType == other.runtimeType &&
data == other.data);
@override
int get hashCode => data.hashCode;
}
widget_test.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:bloc_test/bloc_test.dart';
import 'package:mocktail/mocktail.dart' as mocktail;
import 'package:counter/dummy_cubit.dart';
import 'package:counter/main.dart';
class MockDummyCubit extends MockCubit<AState> implements DummyCubit {}
class AStateFake extends Fake implements AState {}
final dummyCubit = MockDummyCubit();
Widget get counter => MultiBlocProvider(
providers: [
BlocProvider<DummyCubit>(
create: (BuildContext ctx) => dummyCubit,
),
],
child: const MaterialApp(
home: CounterViewer(counter: 1),
),
);
void main() {
setUpAll(() {
mocktail.registerFallbackValue(AStateFake());
});
group('Counter viewer', () {
mocktail.when(() => dummyCubit.state).thenReturn(InitState());
testWidgets('should build', (WidgetTester tester) async {
await tester.pumpWidget(counter);
});
});
}
运行测试时,我收到此错误:
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?
并删除该mocktail.when
行,我收到此错误:
The following _TypeError was thrown building CounterViewer:
type 'Null' is not a subtype of type 'AState'
我该如何解决这个问题?
如何控制 DummyCubit 发出的状态?