I am trying to test my submit button which fires a bloc event onPress.
SubmitButton.dart - Widget
class AuthenticationSubmitButton extends StatefulWidget {
final String buttonLabel;
final TextEditingController _userEmailController;
final TextEditingController _passwordController;
AuthenticationSubmitButton(
this.buttonLabel, this._userEmailController, this._passwordController);
@override
_AuthenticationSubmitButtonState createState() =>
_AuthenticationSubmitButtonState();
}
class _AuthenticationSubmitButtonState
extends State<AuthenticationSubmitButton> {
@override
Widget build(BuildContext context) {
Size screenSize = MediaQuery.of(context).size;
final _authBloc = BlocProvider.of<AuthenticationBloc>(context);
return Container(
child: FlatButton.icon(
height: screenSize.height * 0.07,
minWidth: screenSize.width * 0.5,
padding: EdgeInsets.all(10),
color: Colors.green,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
onPressed: () {
final email = widget._userEmailController.text.trim();
final password = widget._passwordController.text.trim();
_authBloc.add(UserLoginEvent(email, password));
},
icon: Icon(Icons.keyboard_return_rounded),
label: Text(
widget.buttonLabel,
style: SubmitButtonStyle,
),
),
);
}
}
As you can see I am calling the event UserLoginEvent
authentication_events.dart
@immutable
abstract class AuthenticationEvent {}
/**
* Login Event
* Logout Event
*/
class UserLoginEvent extends AuthenticationEvent {
final String userEmail;
final String userPassword;
UserLoginEvent(this.userEmail, this.userPassword);
}
class ClearLoginEvent extends AuthenticationEvent {
}
And here is my authentication states
authentication_states.dart
@immutable
abstract class AuthenticationState extends Equatable {
}
class AuthenticationInitial extends AuthenticationState {
@override
List<Object> get props => [];
}
/**
* LoginSuccessful
* LoginFailed
* LogoutSuccessful
*/
class LoginSuccessful extends AuthenticationState {
@override
List<Object> get props => [];
}
class LoginError extends AuthenticationState {
@override
List<Object> get props => [];
}
authentication_bloc.dart
class AuthenticationBloc
extends Bloc<AuthenticationEvent, AuthenticationState> {
AuthenticationBloc({this.userRepository}) : super(AuthenticationInitial());
UserRepository userRepository;
@override
Stream<AuthenticationState> mapEventToState(
AuthenticationEvent event,
) async* {
if (event is UserLoginEvent) {
UserRepository repository = userRepository ?? UserRepository();
try {
bool loggedIn = await repository.authenticateUserWithCredentials(
event.userEmail, event.userPassword);
if (loggedIn) {
yield LoginSuccessful();
} else {
yield LoginError();
}
} catch (e) {
yield EmptyLoginCredentials();
}
} else if (event is ClearLoginEvent) {
yield AuthenticationInitial();
}
}
}
And finally my test for submit button
> submit_button_test.dart
class MockAuthBloc extends MockBloc<AuthenticationState>
implements AuthenticationBloc {}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
MockAuthBloc authBloc = MockAuthBloc();
TextEditingController _userEmailController;
TextEditingController _passwordController;
setUp(() {
_userEmailController = TextEditingController();
_passwordController = TextEditingController();
authBloc = MockAuthBloc();
});
tearDown(() {
_userEmailController.dispose();
_passwordController.dispose();
authBloc?.close();
});
///Provide Material App for giving access to MediaQuery
///Wrap any widget that needs Material widget
Widget buildTestableWidget(Widget widget) {
return MediaQuery(
data: MediaQueryData(),
child: BlocProvider.value(
value: authBloc,
child: MaterialApp(
home: Material(
child: widget,
),
),
),
);
}
group('Testing Submit button |', () {
testWidgets('description', (WidgetTester tester) async {
whenListen(
authBloc,
Stream.fromIterable(<AuthenticationState>[LoginSuccessful()]),
);
await tester.pumpWidget(buildTestableWidget(AuthenticationSubmitButton(
'Submit', _userEmailController, _passwordController)));
final buttonFinder = find.byType(FlatButton);
final button = tester.firstWidget(buttonFinder);
});
});
}
Could you please tell me what am I doing wrong here?
Below is my error
00:03 +19: /home/bhuvanesh/code/kaadhal_host_client/test/screens/Authentication/widgets/submit_button_test.dart: Testing Submit button | description
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building AuthenticationSubmitButton(dirty, dependencies:
[MediaQuery], state: _AuthenticationSubmitButtonState#da4f9):
BlocProvider.of() called with a context that does not contain a Bloc/Cubit of type
AuthenticationBloc.
No ancestor could be found starting from the context that was passed to
BlocProvider.of<AuthenticationBloc>().
This can happen if the context you used comes from a widget above the BlocProvider.
The context used was: AuthenticationSubmitButton(dirty, dependencies: [MediaQuery], state:
_AuthenticationSubmitButtonState#da4f9)
The relevant error-causing widget was:
AuthenticationSubmitButton
file:///home/bhuvanesh/code/kaadhal_host_client/test/screens/Authentication/widgets/submit_button_test.dart:57:51
When the exception was thrown, this was the stack:
#0 BlocProvider.of (package:flutter_bloc/src/bloc_provider.dart:121:7)
#1 _AuthenticationSubmitButtonState.build (package:kaadhal_host_client/screens/Authentication/widgets/submit_button.dart:26:36)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4744:28)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4627:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4800:11)
#5 Element.rebuild (package:flutter/src/widgets/framework.dart:4343:5)
#6 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4606:5)
#7 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4791:11)
#8 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4601:5)
... Normal element mounting (174 frames)
#182 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3569:14)
#183 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6236:32)
... Normal element mounting (267 frames)
#450 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3569:14)
#451 Element.updateChild (package:flutter/src/widgets/framework.dart:3327:18)
#452 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4652:16)
#453 _InheritedProviderScopeElement.performRebuild (package:provider/src/inherited_provider.dart:426:11)
#454 Element.rebuild (package:flutter/src/widgets/framework.dart:4343:5)
#455 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4606:5)
#456 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4601:5)
... Normal element mounting (7 frames)
#463 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:223:11)
... Normal element mounting (7 frames)
#470 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:223:11)
... Normal element mounting (7 frames)
#477 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3569:14)
#478 Element.updateChild (package:flutter/src/widgets/framework.dart:3324:20)
#479 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1252:16)
#480 RenderObjectToWidgetElement.update (package:flutter/src/widgets/binding.dart:1230:5)
#481 RenderObjectToWidgetElement.performRebuild (package:flutter/src/widgets/binding.dart:1244:7)
#482 Element.rebuild (package:flutter/src/widgets/framework.dart:4343:5)
#483 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2730:33)
#484 AutomatedTestWidgetsFlutterBinding.drawFrame (package:flutter_test/src/binding.dart:1088:18)
#485 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:302:5)
#486 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1117:15)
#487 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1055:9)
#488 AutomatedTestWidgetsFlutterBinding.pump.<anonymous closure> (package:flutter_test/src/binding.dart:961:9)
#491 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:72:41)
#492 AutomatedTestWidgetsFlutterBinding.pump (package:flutter_test/src/binding.dart:948:27)
#493 WidgetTester.pumpWidget.<anonymous closure> (package:flutter_test/src/widget_tester.dart:524:22)
#496 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:72:41)
#497 WidgetTester.pumpWidget (package:flutter_test/src/widget_tester.dart:521:27)
#498 main.<anonymous closure>.<anonymous closure> (file:///home/bhuvanesh/code/kaadhal_host_client/test/screens/Authentication/widgets/submit_button_test.dart:57:20)
#499 main.<anonymous closure>.<anonymous closure> (file:///home/bhuvanesh/code/kaadhal_host_client/test/screens/Authentication/widgets/submit_button_test.dart:46:32)
#500 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:146:29)
#511 FakeAsync.flushMicrotasks (package:fake_async/fake_async.dart:193:32)
#512 AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1189:17)
#513 AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1177:35)
(elided 29 frames from dart:async and package:stack_trace)
════════════════════════════════════════════════════════════════════════════════════════════════════
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following StateError was thrown running a test:
Bad state: No element
When the exception was thrown, this was the stack:
#0 Iterable.first (dart:core/iterable.dart:524:7)
#1 WidgetController.firstWidget (package:flutter_test/src/controller.dart:79:30)
#2 main.<anonymous closure>.<anonymous closure> (file:///home/bhuvanesh/code/kaadhal_host_client/test/screens/Authentication/widgets/submit_button_test.dart:60:29)
<asynchronous suspension>
#3 main.<anonymous closure>.<anonymous closure> (file:///home/bhuvanesh/code/kaadhal_host_client/test/screens/Authentication/widgets/submit_button_test.dart)
#4 testWidgets.<anonymous closure&