Describe the bug
I made a repo for reproduction:
https://github.com/JSANL/bloc_problem
When I run the test this is the output:
HomeworkPageBloc event: LoadHomeworks
HomeworkPageBloc.mapEventToState: LoadHomeworks
HomeworkPageBloc transition: Transition { currentState: HomeworkPageStateLoading, event: LoadHomeworks, nextState: Success(completed: onLoad, open: onLoad) }
HomeworkPageBloc event: SortingChanged
Even though the SortingChanged event was called in the bloc delegate, HomeworkPageBloc.mapEventToState was not called with it. The beginning with LoadHomeworks works just fine though.
I already looked at other issues, where the problem seems to be with the equality, but I'm not certain if that is the case right here. If it is I couldn't figure it out yet.
To Reproduce
Steps to reproduce the behavior:
pub getpub run testExpected behavior
Passing the test.
That means that HomeworkPageBloc.mapEventToState should be called with the SortingChanged Event and that this should call SortingChanged on the MockOpenHomeworksViewBloc. A Success state of the HomeworkPageBloc should lastly be returned by HomeworkPageBloc.state which contains the String "onSorting" (the result of the Success state of MockOpenHomeworksViewBloc).
(Basically the HomeworkPageBloc shoud delegate the SortingChanged to the MockOpenHomeworksViewBloc and return the result).
*Logs *
[✓] Flutter (Channel unknown, v1.9.1+hotfix.4, on Mac OS X 10.14.6 18G103, locale de-DE)
• Flutter version 1.9.1+hotfix.4 at /Users/jonassander/development/flutter
• Framework revision cc949a8e8b (2 weeks ago), 2019-09-27 15:04:59 -0700
• Engine revision b863200c37
• Dart version 2.5.0
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
• Android SDK at /Users/jonassander/Library/Android/sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-29, build-tools 28.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 10.2.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 10.2.1, Build version 10E1001
• CocoaPods version 1.6.0
[✓] Android Studio (version 3.5)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 40.1.2
• Dart plugin version 191.8423
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
[✓] VS Code (version 1.39.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.5.1
[✓] Connected device (1 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 9 (API 28) (emulator)
• No issues found!
Hi @JSANL 👋
Thanks for opening an issue!
I took a quick look and the reason why mapEventToState isn't being called with SortingChanged is because in your _mapLoadHomeworksToState you return an Observable that never completes. The bloc is waiting for that Observable to complete before processing the next event which is why SortingChanged never makes it into mapEventToState. I would recommend you take a look at the flutter_bloc_with_stream example of how to handle this case properly without blocking the event loop.
In addition, I would highly recommend using mockito when testing your blocs so that you don't have to manually write mock implementations.
You can check out a fully tested app using the bloc library here.
Hope that helps 👍
Thank you so much for answering, this will probably be reason! I'm very sorry for asking such questions, I just sat there for hours and could not figure it out😂
Thanks for the tips :)
Hey @felangel . I have same issue.If observable uncomplete,then mapEventToState can not call.I still dont unserstand why ?,Can you explain help me ? I found in core have this functions,dose it take this ?
dart
void _bindStateSubject() {
Event currentEvent;
transformStates(transformEvents(_eventSubject, (Event event) {
currentEvent = event;
return mapEventToState(currentEvent).handleError(_handleError);
})).forEach(
(State nextState) {
if (state == nextState || _stateSubject.isClosed) return;
final transition = Transition(
currentState: state,
event: currentEvent,
nextState: nextState,
);
try {
BlocSupervisor.delegate.onTransition(this, transition);
onTransition(transition);
_stateSubject.add(nextState);
} on Object catch (error) {
_handleError(error);
}
},
);
}
Most helpful comment
Thank you so much for answering, this will probably be reason! I'm very sorry for asking such questions, I just sat there for hours and could not figure it out😂
Thanks for the tips :)