Reputation: 1768
Im five hours trying solve it, doesn't work nothing. I wanna test bloc class that use stream and sink data after load data from internet. The use case test work well but the bloc class was a huge headache today, this already work on app, but the test I really dont know how to solve
file bloc.dart
class Bloc {
final UseCase _useCase;
Bloc(this._useCase);
final _controller = StreamController.broadcast();
Stream get stream => _controller.stream;
doSomething() async {
ResponseModel responseModel = await _useCase.call();
_controller.sink.add(responseModel);//<-- I would like test this
}
dispose() {
_controller.close();
}
}
This is the unit test class bloc_test.dart
class UseCaseMock extends Mock implements UseCase {}
main() {
UseCase useCase;
Bloc bloc;
setUp(() async {
useCase = UseCaseMock();
bloc = Bloc(useCase);
});
tearDown(() {
bloc.dispose();
});
group('Test Bloc', () {
test('load stuff must sink Response ', () async {
when(useCase.call())
.thenAnswer((_) async => ResponseModel('id','name'));
//FIRST I TRY It, DOESNT WORK
// await expectLater( bloc.stream, emits(isA<ResponseModel>()));
bloc.stream.listen((response) {
//print(response) <-----return null I THINK HERE IS THE PROBLEM
expect(response, isA<ResponseModel>());
});
await bloc.doSomething();
});
});
}
Please, would you know how to solve it? Thanks
Upvotes: 3
Views: 4621
Reputation: 1768
Solved! my usecase has a method "call" with an optional parameter
Future<ResponseModel> call( {String value });
I was mocking wrong as below
when(useCase.call()) <----------------here is the error
.thenAnswer((_) async => ResponseModel('id','name'));
Inside true Bloc class(not a pseudocode that I had posted) I execute a usecase using the parameter
// this is the true doSomething() method on my app
loadCoupons(String storeId) async {
final result = await searchCouponUseCase(storeId: storeId);
_controller.sink.add(result);
}
And the solution is: Mock using optional parameter(if it will be called)! I was testing without parameter because when putting "any" inside the test like a when( useCase.call( any))... not compile.
when(useCase.call( value: '' )) <-----solved
.thenAnswer((_) async => ResponseModel('id','name'));
Upvotes: 3
Reputation: 7726
You can run your async operation before using expectLater
for assertion. Also remove the await
from bloc.doSomething()
as it times out otherwise.
This will work.
test('load stuff must sink Response ', () async {
when(useCase.call())
.thenAnswer((_) async => ResponseModel('id','name'));
bloc.doSomething();
await expectLater(bloc.stream, emits(isA<Response>()));
});
Upvotes: 1