Reputation: 691
I'm having some issues using bloc_test and Mockito. I have a bloc that has a use case dependency and I'm creating a mock of the Use Case with values to test it with.
This is my bloc:
class IssuesBloc extends Bloc<IssuesEvent, IssuesState> {
final GetIssues _getIssues;
IssuesBloc(this._getIssues) : super(IssuesInitial());
@override
Stream<IssuesState> mapEventToState(
IssuesEvent event,
) async* {
// here is my action code that is not the necesary to show for the question of my bloc
}
}
This is my bloc mockito (I'm not sure how to pass the mockito use case to the MockIssuesBloc):
class MockIssuesBloc extends MockBloc<IssuesState> implements IssuesBloc {}
This is my use case with a list of data to test:
class MockGetIssues extends Mock implements GetIssues {
Future<Either<AppError, List<IssuesModel>>> call(
PageParams pageParams) async {
return Future.delayed(
const Duration(
milliseconds: 100,
),
() => right(
[
IssuesModel(id: 1),
IssuesModel(id: 2),
IssuesModel(id: 3),
IssuesModel(id: 4),
IssuesModel(id: 5),
IssuesModel(id: 6),
IssuesModel(id: 7),
IssuesModel(id: 8),
IssuesModel(id: 9),
IssuesModel(id: 10),
IssuesModel(id: 11),
IssuesModel(id: 12),
IssuesModel(id: 13),
IssuesModel(id: 14),
IssuesModel(id: 15),
IssuesModel(id: 16),
IssuesModel(id: 17),
IssuesModel(id: 18),
IssuesModel(id: 19),
IssuesModel(id: 20),
].getRange(0, pageParams.take),
),
);
}
}
This is my test main (I have 3 different ways and get error in the 3):
void main() {
group('IssuesBloc', () {
MockIssuesBloc issuesBloc;
MockGetIssues mockGetIssues;
setUpAll(() {
mockGetIssues = MockGetIssues();
issuesBloc = MockIssuesBloc();
});
blocTest( // throws Bad state: Mock method was not called within `when()`. Was a real method called?
'bloc: emits [IssuesInitial(), IssuesLoadedState(),] when successful',
build: () {
when(getIssues(PageParams()))
.thenAnswer((value) async => right([IssuesModel(id: 1)]));
return IssuesBloc(getIssues);
},
act: (bloc) => bloc.add(LoadIssues()),
expect: [
IssuesInitial(),
isA<IssuesLoadedState>(),
],
);
// Bad state: Mock method was not called within `when()`. Was a real method called?
test('when: emits [IssuesInitial(), IssuesLoadedState(),] when successful', () {
when(mockGetIssues(PageParams()))
.thenAnswer((value) async => right([IssuesModel(id: 1)]));
final bloc = IssuesBloc(mockGetIssues);
bloc.add(LoadIssues());
emitsExactly(bloc, [
IssuesInitial(),
isA<IssuesLoadedState>(),
]);
});
// type '_BroadcastSubscription<Type>' is not a subtype of type 'StreamSubscription<IssuesState>'
test("whenListen: emits [IssuesInitial(), IssuesLoadedState(),] when successful", () {
whenListen(
issuesBloc,
Stream.fromIterable([IssuesInitial]),
);
expectLater(
issuesBloc,
emitsInOrder(
[
IssuesInitial,
isA<IssuesLoadedState>()
],
),
);
});
});
}
I also used the bloc without using mockito and in the 3 cases I get the next error: Bad state: Mock method was not called within when()
. Was a real method called?
I'm not sure why I'm facing this issue
Upvotes: 2
Views: 2132
Reputation: 26
The problem here is because in the blocTest build function you didn't create the stub for the mock, instead you used the getIssues instead of the mocked version. Below is the fixed code. In case someone else is facing the same issue.
For more information about bloc_test and mocks, I suggest this tutorial on youtube: Bloc Test Tutorial
'bloc: emits [IssuesInitial(), IssuesLoadedState(),] when successful',
build: () {
when(mockGetIssues(PageParams()))
.thenAnswer((value) async => right([IssuesModel(id: 1)]));
return IssuesBloc(mockGetIssues);
},
act: (bloc) => bloc.add(LoadIssues()),
expect: [
IssuesInitial(),
isA<IssuesLoadedState>(),
],
);
Upvotes: 0
Reputation: 11
The underlying mock provided by MockBloc is a mock from the Mocktail package (https://pub.dev/packages/mocktail).
You need to use Mocktail's when
to stub these's mocks. Mockito also provides a when
method, but it's incompatible (thus the runtime error you received).
Upvotes: 1