Flutter test , stubbing a method that uses dartz fails - flutter

Here's the implicated methods of the cubit I'm testing:
void authCheck() {
if (_authUser != null) {
emit(AuthState.authenticated(_authUser!));
if (kDebugMode) {
// ignore: avoid_print
print(_authUser!);
}
} else {
emit(const AuthState.unauthenticated());
signInAnonymously();
}
}
Future<void> signInAnonymously() async {
final either = await _authRepository.signInAnonymously();
either.fold(
(failure) => _showFailureToast(failure),
(auth) => emit(AuthState.authenticated(_authUser!)),
);
}
I'm testing the unauthenticated part of authCheck, here's the test:
blocTest('should emit [Unauthenticated] when user is not authenticated',
build: () {
when(authCubit.signInAnonymously())
.thenAnswer((_) => Future.value(null));
when(mockIAuthRepository.getSignedInUser()).thenReturn(null);
return authCubit;
},
act: (AuthCubit authcubit) {
authcubit.authCheck();
},
expect: () => [const AuthState.unauthenticated()]);
But when stubbing authCubit.signInAnonymously to return a Future<void> I get this error:
UnimplementedError: fold
package:test_api Fake.noSuchMethod
package:dartz/src/either.dart 8:5 _FakeEither_0.fold
package:mage_duel/application/auth/auth_cubit.dart 38:12 AuthCubit.signInAnonymously
===== asynchronous gap ===========================
dart:async _asyncThenWrapperHelper
test/application/auth/auth_cubit_test.dart 51:26 main.<fn>.<fn>
package:bloc_test/src/bloc_test.dart 196:29 testBloc.<fn>.<fn>
===== asynchronous gap ===========================
dart:async _asyncThenWrapperHelper
package:bloc_test/src/bloc_test.dart testBloc.<fn>.<fn>
dart:async runZonedGuarded
package:bloc_test/src/bloc_test.dart 192:13 testBloc.<fn>
package:bloc_test/src/bloc_test.dart 191:5 testBloc.<fn>
dart:async runZoned
package:bloc/src/bloc_overrides.dart 46:26 BlocOverrides.runZoned
package:bloc_test/src/bloc_test.dart 190:23 testBloc
package:bloc_test/src/bloc_test.dart 156:13 blocTest.<fn>
package:bloc_test/src/bloc_test.dart 155:5 blocTest.<fn>
type 'Future<void>' is not a subtype of type 'Future<Either<AuthFailure, Unit>>' in type cast
test/application/auth/auth_cubit_test.mocks.dart 50:11 MockIAuthRepository.signInAnonymously
package:mage_duel/application/auth/auth_cubit.dart 37:42 AuthCubit.signInAnonymously
package:mage_duel/application/auth/auth_cubit.dart 32:7 AuthCubit.authCheck
test/application/auth/auth_cubit_test.dart 57:21 main.<fn>.<fn>
package:bloc_test/src/bloc_test.dart 201:24 testBloc.<fn>.<fn>
===== asynchronous gap ===========================
dart:async _completeOnAsyncError
package:mage_duel/application/auth/auth_cubit.dart AuthCubit.signInAnonymously
package:mage_duel/application/auth/auth_cubit.dart 32:7 AuthCubit.authCheck
test/application/auth/auth_cubit_test.dart 57:21 main.<fn>.<fn>
package:bloc_test/src/bloc_test.dart 201:24 testBloc.<fn>.<fn>
===== asynchronous gap ===========================
dart:async _asyncThenWrapperHelper
package:bloc_test/src/bloc_test.dart testBloc.<fn>.<fn>
dart:async runZonedGuarded
package:bloc_test/src/bloc_test.dart 192:13 testBloc.<fn>
package:bloc_test/src/bloc_test.dart 191:5 testBloc.<fn>
dart:async runZoned
package:bloc/src/bloc_overrides.dart 46:26 BlocOverrides.runZoned
package:bloc_test/src/bloc_test.dart 190:23 testBloc
package:bloc_test/src/bloc_test.dart 156:13 blocTest.<fn>
package:bloc_test/src/bloc_test.dart 155:5 blocTest.<fn>

Related

I get the error The following _CastError was thrown building _BodyBuilder: type 'Null' is not a subtype of type 'JokeBloc' in type cast

Here is the My App Screen:
import 'package:api_call_sample/Repository/JokeRepository.dart';
import 'package:api_call_sample/bloc/jokeevent.dart';
import 'package:api_call_sample/bloc/jokestate.dart';
import 'package:flutter/material.dart';
import "package:api_call_sample/bloc/jokebloc.dart";
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: BlocProvider(
create: (context) => JokeBloc(
RepositoryProvider.of<JokeRepository>(context),
)..add(LoadJokeEvent()),
child: const HomeScreen()),
);
}
}
Here is the HomeScreen Screen :Getting Error in the Bloc Builder screen
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Joke Api"),
),
**body: Column( children: [**
**BlocBuilder<JokeBloc, JokeState>(builder: (context, state) {**
print(state);
if (state is JokeLoadingState) {
print("Loading state");
return const CircularProgressIndicator();
}
if (state is JokeLoadedState) {
print(state.jokeData.toString());
return ExpansionTile(
title: Text(state.jokeData.setup),
children: [
Container(
margin: const EdgeInsets.all(5.0),
child: Text(state.jokeData.delivery))
],
);
}
if (state is JokeErrorState) {
print("Error state");
return Text(state.error.toString());
}
return Container();
}),
ElevatedButton(
onPressed: () {
BlocProvider.of<JokeBloc>(context).add(LoadJokeEvent());
},
child: const Text('Load More'))
]),
);
}
}
Here is the JokeBloc:
import 'package:bloc/bloc.dart';
import 'jokestate.dart';
import 'jokeevent.dart';
import 'package:api_call_sample/Repository/JokeRepository.dart';
class JokeBloc extends Bloc<JokeEvent,JokeState>{
final JokeRepository _jokeRepository;
JokeBloc(this._jokeRepository) : super(JokeLoadingState())
{
on<LoadJokeEvent>((event, emit) async {
emit(JokeLoadingState());
try {
final joke = await _jokeRepository.getJoke();
emit(JokeLoadedState(joke));
} catch (e) {
emit(JokeErrorState(e.toString()));
}
});
}
}
Error Message :
The following _CastError was thrown building _BodyBuilder:
type 'Null' is not a subtype of type 'JokeBloc' in type cast.
The relevant error-causing widget was:Scaffold Scaffold:file:///Applications/flutter/api_call_sample/lib/main.dart:37:12
The relevant error-causing widget was:
Scaffold Scaffold:file:///Applications/flutter/api_call_sample/lib/main.dart:37:12
When the exception was thrown, this was the stack:
#0 _CreateInheritedProviderState.value (package:provider/src/inherited_provider.dart:786:72)
#1 _CreateInheritedProviderState.debugFillProperties (package:provider/src/inherited_provider.dart:806:44)
#2 _InheritedProviderScopeElement.debugFillProperties (package:provider/src/inherited_provider.dart:631:20)
#3 DiagnosticableNode.builder.<anonymous closure> (package:flutter/src/foundation/diagnostics.dart:2992:17)
#4 DiagnosticableNode.builder (package:flutter/src/foundation/diagnostics.dart:2995:8)
#5 DiagnosticableNode.getProperties (package:flutter/src/foundation/diagnostics.dart:3009:105)
#6 TextTreeRenderer._debugRender (package:flutter/src/foundation/diagnostics.dart:1244:63)
#7 TextTreeRenderer.render (package:flutter/src/foundation/diagnostics.dart:1121:14)
#8 DiagnosticsNode.toStringDeep.<anonymous closure> (package:flutter/src/foundation/diagnostics.dart:1776:9)
#9 DiagnosticsNode.toStringDeep (package:flutter/src/foundation/diagnostics.dart:1783:6)
#10 DiagnosticsNode.toString.<anonymous closure> (package:flutter/src/foundation/diagnostics.dart:1694:18)
#11 DiagnosticsNode.toString (package:flutter/src/foundation/diagnostics.dart:1706:6)
#12 Diagnosticable.toString.<anonymous closure> (package:flutter/src/foundation/diagnostics.dart:3168:78)
#13 Diagnosticable.toString (package:flutter/src/foundation/diagnostics.dart:3170:6)
#14 _StringBase._interpolate (dart:core-patch/string_patch.dart:853:19)
#15 RepositoryProvider.of (package:flutter_bloc/src/repository_provider.dart:78:12)
#16 MyApp.build.<anonymous closure> (package:api_call_sample/main.dart:20:36)
#17 _CreateInheritedProviderState.value (package:provider/src/inherited_provider.dart:736:36)
#18 _InheritedProviderScopeElement.value (package:provider/src/inherited_provider.dart:590:33)
#19 Provider.of (package:provider/src/provider.dart:303:37)
#20 ReadContext.read (package:provider/src/provider.dart:649:21)
#21 _BlocBuilderBaseState.initState (package:flutter_bloc/src/bloc_builder.dart:130:36)
#22 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4942:57)
#23 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4781:5)
#24 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3817:16)
#25 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6350:36)
#26 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6362:32)
... Normal element mounting (19 frames)
#45 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3817:16)
#46 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6350:36)
#47 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6362:32)
... Normal element mounting (99 frames)
#146 _InheritedProviderScopeElement.mount (package:provider/src/inherited_provider.dart:411:11)
... Normal element mounting (7 frames)
#153 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
... Normal element mounting (7 frames)
#160 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
... Normal element mounting (275 frames)
#435 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3817:16)
#436 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6350:36)
#437 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6362:32)
... Normal element mounting (377 frames)
#814 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3817:16)
#815 Element.updateChild (package:flutter/src/widgets/framework.dart:3551:18)
#816 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1202:16)
#817 RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1171:5)
#818 RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:1119:18)
#819 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2597:19)
#820 RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1118:13)
#821 WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:953:7)
#822 WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:933:7)
(elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)
Another exception was thrown: Each child must be laid out exactly once.
The way you create the JokeBloc in the BlocProvider doesn't work within this lifecycle,
replacing this code with the code below should fix the problem
create: (_) => JokeBloc(JokeRepository())

Flutter Riverpod WidgetTest not exceeding past loading state

UPDATE: Rewrote Test in a same way I test another consumer widget, which actually works, but it still doesn't work for my test and I can't get my head around why :(
Current approach:
void main() {
final List<Exercise> _mockExercises = [
Exercise(
userID: 'uid123',
title: 'Übung1',
repetitions: 10,
isCompleted: false,
isVideo: false,
unit: 'Sekunden',
description: 'Some description',
exerciseID: '42',
imageUrl: 'https://via.placeholder.com/150',
thumbUrl: 'https://via.placeholder.com/150'),
Exercise(
userID: 'uid123',
title: 'Übung2',
repetitions: 20,
isCompleted: false,
isVideo: false,
unit: 'Sekunden',
description: 'Some description2',
exerciseID: '43',
imageUrl: 'https://via.placeholder.com/150',
thumbUrl: 'https://via.placeholder.com/150'),
];
testWidgets('user exercise list - pump', (WidgetTester tester) async {
await mockNetworkImagesFor(() async {
await tester.pumpWidget(ProviderScope(
child: MyApp(),
/// overrides: provide fake asyncvalue data to stream
overrides: [
exerciseCollectionStream
.overrideWithValue(AsyncValue.data(_mockExercises))
],
));
await tester.pump();
// The first frame is a loading state.
expect(find.byType(Loading), findsOneWidget);
await tester.pumpAndSettle();
// await Future.delayed(Duration(seconds: 2));
// await tester.pumpAndSettle();
// No-longer loading
expect(find.byType(Loading), findsNothing);
});
});
}
I'm trying to write a widget test for a Listview Widget and I never get past the loading state of the "Asyncvalue".when state in my test and it is stuck in loading.
I tried to approach the test like in the Riverpod docs or as explained here: https://codewithandrea.com/videos/flutter-state-management-riverpod/
But I got stuck :-/
We have Loading() Widget, that we test against to see if it disappears, but it doesn't..
That's the code of the test:
class ExerciseRepo {
// ignore: missing_return
Future<List<Exercise>> exerciseList() {
// should get data from database
}
}
final exerciseRepoProvider = Provider((ref) => ExerciseRepo());
final exerciseListProvider = FutureProvider<List<Exercise>>((ref) {
final repo = ref.watch(exerciseRepoProvider);
return repo.exerciseList();
});
class MockExercisesRepository extends Mock implements ExerciseRepo {
#override
Future<List<Exercise>> exerciseList() {
return Future.value([
Exercise(
title: 'Übung1',
repetitions: 10,
isCompleted: false,
isVideo: false,
unit: 'Sekunden',
description: 'Some description',
exerciseID: '42',
imageUrl: 'https://via.placeholder.com/150',
thumbUrl: 'https://via.placeholder.com/150'),
Exercise(
title: 'Übung2',
repetitions: 20,
isCompleted: false,
isVideo: false,
unit: 'Sekunden',
description: 'Some description2',
exerciseID: '43',
imageUrl: 'https://via.placeholder.com/150',
thumbUrl: 'https://via.placeholder.com/150'),
]);
}
}
void main() {
testWidgets('override repositoryProvider', (WidgetTester tester) async {
await mockNetworkImagesFor(() async {
await tester.pumpWidget(
ProviderScope(
overrides: [
exerciseListProvider.overrideWithProvider(
Provider((ref) => MockExercisesRepository))
],
child: MaterialApp(
home: Builder(builder: (context) {
return UserExerciseList();
}),
),
),
);
// The first frame is a loading state.
expect(find.byType(Loading), findsOneWidget);
await tester.pump();
await tester.pumpAndSettle();
// await Future.delayed(Duration(seconds: 3));
await tester.pumpAndSettle();
// No-longer loading
expect(find.byType(Loading), findsNothing);
});
});
}
The error message is:
The following TestFailure object was thrown running a test:
Expected: no matching nodes in the widget tree
Actual: _WidgetTypeFinder:<exactly one widget with type "Loading" (ignoring offstage widgets):
Loading>
Which: means one was found but none were expected
When the exception was thrown, this was the stack:
#4 main.<anonymous closure>.<anonymous closure> (file:///.../test/widget_exercise_list_test.dart:77:7)
<asynchronous suspension>
#5 main.<anonymous closure>.<anonymous closure> (file:///.../test/widget_exercise_list_test.dart)
#10 HttpOverrides.runZoned (dart:_http/overrides.dart:55:26)
#11 mockNetworkImagesFor (package:network_image_mock/src/network_image_mock.dart:9:24)
#12 main.<anonymous closure> (file:///.../test/widget_exercise_list_test.dart:54:11)
#13 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:146:29)
<asynchronous suspension>
#14 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart)
#15 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:784:19)
<asynchronous suspension>
#18 TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:764:14)
#19 AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1173:24)
#20 FakeAsync.run.<anonymous closure>.<anonymous closure> (package:fake_async/fake_async.dart:178:54)
#25 withClock (package:clock/src/default.dart:48:10)
#26 FakeAsync.run.<anonymous closure> (package:fake_async/fake_async.dart:178:22)
#31 FakeAsync.run (package:fake_async/fake_async.dart:178:7)
#32 AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:1170:15)
#33 testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:138:24)
#34 Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:175:19)
<asynchronous suspension>
#35 Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart)
#40 Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:173:13)
#41 Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:231:15)
#46 Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:228:5)
#47 Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:383:17)
<asynchronous suspension>
#48 Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart)
#53 Invoker._onRun.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:370:9)
#54 Invoker._guardIfGuarded (package:test_api/src/backend/invoker.dart:415:15)
#55 Invoker._onRun.<anonymous closure> (package:test_api/src/backend/invoker.dart:369:7)
#62 Invoker._onRun (package:test_api/src/backend/invoker.dart:368:11)
#63 LiveTestController.run (package:test_api/src/backend/live_test_controller.dart:153:11)
#64 RemoteListener._runLiveTest.<anonymous closure> (package:test_api/src/remote_listener.dart:256:16)
#69 RemoteListener._runLiveTest (package:test_api/src/remote_listener.dart:255:5)
#70 RemoteListener._serializeTest.<anonymous closure> (package:test_api/src/remote_listener.dart:208:7)
#88 _GuaranteeSink.add (package:stream_channel/src/guarantee_channel.dart:125:12)
#89 new _MultiChannel.<anonymous closure> (package:stream_channel/src/multi_channel.dart:159:31)
#93 CastStreamSubscription._onData (dart:_internal/async_cast.dart:85:11)
#127 new _WebSocketImpl._fromSocket.<anonymous closure> (dart:_http/websocket_impl.dart:1145:21)
#135 _WebSocketProtocolTransformer._messageFrameEnd (dart:_http/websocket_impl.dart:338:23)
#136 _WebSocketProtocolTransformer.add (dart:_http/websocket_impl.dart:232:46)
#146 _Socket._onData (dart:io-patch/socket_patch.dart:2044:41)
#155 new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1580:33)
#156 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1076:14)
(elided 115 frames from dart:async and package:stack_trace)
This was caught by the test expectation on the following line:
file:///.../test/widget_exercise_list_test.dart line 77
The test description was:
override repositoryProvider
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: override repositoryProvider
That's the relevant part of the UserExerciseList()
#override
Widget build(BuildContext context, ScopedReader watch) {
AsyncValue<List<Exercise>> userExercisesList =
watch(exerciseCollectionStream);
return userExercisesList.when(
error: (error, stack) => ErrorInfo(error, stack),
loading: () => Loading(),
data: (List<Exercise> exercises) {
I also replaced Future with stream in my tests, didn't work either :-/ Any help is highly appreciated!
Many thanks!
I had to try out using several pumps to get a my mock data to return and change the state.
await tester.pumpWidget(ProviderScope(child: const MyApp()));
await tester.pump(Duration(seconds: 1));
await tester.pump(Duration(seconds: 1));
await tester.pump(Duration(seconds: 1));
expect(find.text("Sample Text"), findsOneWidget);
pumpAndSettle did not work.

Flutter-Test: Getting BlocProvider.of() called with a context that does not container Bloc

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>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:146:29)
<asynchronous suspension>
#5 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart)
#6 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:784:19)
<asynchronous suspension>
#9 TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:764:14)
#10 AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1173:24)
#11 FakeAsync.run.<anonymous closure>.<anonymous closure> (package:fake_async/fake_async.dart:178:54)
#16 withClock (package:clock/src/default.dart:48:10)
#17 FakeAsync.run.<anonymous closure> (package:fake_async/fake_async.dart:178:22)
#22 FakeAsync.run (package:fake_async/fake_async.dart:178:7)
#23 AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:1170:15)
#24 testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:138:24)
#25 Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:175:19)
<asynchronous suspension>
#26 Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart)
#31 Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:173:13)
#32 Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:231:15)
#37 Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:228:5)
#38 Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:383:17)
<asynchronous suspension>
#39 Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart)
#44 Invoker._onRun.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:370:9)
#45 Invoker._guardIfGuarded (package:test_api/src/backend/invoker.dart:415:15)
#46 Invoker._onRun.<anonymous closure> (package:test_api/src/backend/invoker.dart:369:7)
#53 Invoker._onRun (package:test_api/src/backend/invoker.dart:368:11)
#54 LiveTestController.run (package:test_api/src/backend/live_test_controller.dart:153:11)
#55 RemoteListener._runLiveTest.<anonymous closure> (package:test_api/src/remote_listener.dart:256:16)
#60 RemoteListener._runLiveTest (package:test_api/src/remote_listener.dart:255:5)
#61 RemoteListener._serializeTest.<anonymous closure> (package:test_api/src/remote_listener.dart:208:7)
#79 _GuaranteeSink.add (package:stream_channel/src/guarantee_channel.dart:125:12)
#80 new _MultiChannel.<anonymous closure> (package:stream_channel/src/multi_channel.dart:159:31)
#84 CastStreamSubscription._onData (dart:_internal/async_cast.dart:85:11)
#118 new _WebSocketImpl._fromSocket.<anonymous closure> (dart:_http/websocket_impl.dart:1145:21)
#126 _WebSocketProtocolTransformer._messageFrameEnd (dart:_http/websocket_impl.dart:338:23)
#127 _WebSocketProtocolTransformer.add (dart:_http/websocket_impl.dart:232:46)
#137 _Socket._onData (dart:io-patch/socket_patch.dart:2044:41)
#146 new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1580:33)
#147 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1076:14)
(elided 111 frames from dart:async and package:stack_trace)
The test description was:
description
════════════════════════════════════════════════════════════════════════════════════════════════════
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following message was thrown:
Multiple exceptions (2) were detected during the running of the current test, and at least one was
unexpected.
════════════════════════════════════════════════════════════════════════════════════════════════════
00:03 +19 -1: /home/bhuvanesh/code/kaadhal_host_client/test/screens/Authentication/widgets/submit_button_test.dart: Testing Submit button | description [E]
Test failed. See exception logs above.
The test description was: description
Reasons-
You are coming on this class thought navigator
Your parent is not using same bloc
Solution-
You can use bloc here by passing it to constructor

How do I fix this NoSuchMethodError inFlutter?

I am following along with an online course yet my code throws an error where the instructor's code doesn't. Yes, I've scanned over it to make sure they are identical.
Maybe there is some small detail I've missed. At any rate, can someone please help me fix this error so I can move on?
Here is the get method:
List<Map<String, Object>> get groupedTransactionValues {
return List.generate(7, (index) {
final weekDay = DateTime.now().subtract(
Duration(days: index),
);
var totalSum = 0.0;
for (int i; i < recentTransactions.length; i++) {
if (recentTransactions[i].date.day == weekDay.day &&
recentTransactions[i].date.month == weekDay.month &&
recentTransactions[i].date.year == weekDay.year) {
totalSum += recentTransactions[i].amount;
}
}
return {
'day': DateFormat.E().format(weekDay).substring(0, 1),
'amount': totalSum,
};
});
}
And here is the implementation of it in Flutter:
#override
Widget build(BuildContext context) {
return Card(
elevation: 6,
margin: EdgeInsets.all(20),
child: Row(
children: groupedTransactionValues.map((data) {
}).toList(),
),
);
}
}
And here's the error message:
The following NoSuchMethodError was thrown building Chart(dirty):
The method '<' was called on null.
Receiver: null
Tried calling: <(0)
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 Chart.groupedTransactionValues.<anonymous closure>
package:expense/widgets/chart.dart:19
#2 new List.generate (dart:core-patch/array_patch.dart:78:28)
#3 Chart.groupedTransactionValues
package:expense/widgets/chart.dart:13
#4 Chart.build
package:expense/widgets/chart.dart:45
#5 StatelessElement.build
package:flutter/…/widgets/framework.dart:4620
#6 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4546
#7 Element.rebuild
package:flutter/…/widgets/framework.dart:4262
#8 ComponentElement._firstBuild
package:flutter/…/widgets/framework.dart:4525
#9 ComponentElement.mount
package:flutter/…/widgets/framework.dart:4520
#10 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3490
#11 MultiChildRenderObjectElement.mount
package:flutter/…/widgets/framework.dart:5991
... Normal element mounting (109 frames)
#120 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3490
#121 MultiChildRenderObjectElement.mount
package:flutter/…/widgets/framework.dart:5991
... Normal element mounting (210 frames)
#331 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3490
#332 MultiChildRenderObjectElement.mount
package:flutter/…/widgets/framework.dart:5991
... Normal element mounting (273 frames)
#605 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3490
#606 Element.updateChild
package:flutter/…/widgets/framework.dart:3258
#607 RenderObjectToWidgetElement._rebuild
package:flutter/…/widgets/binding.dart:1174
#608 RenderObjectToWidgetElement.mount
package:flutter/…/widgets/binding.dart:1145
#609 RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure>
package:flutter/…/widgets/binding.dart:1087
#610 BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2620
#611 RenderObjectToWidgetAdapter.attachToRenderTree
package:flutter/…/widgets/binding.dart:1086
#612 WidgetsBinding.attachRootWidget
package:flutter/…/widgets/binding.dart:927
#613 WidgetsBinding.scheduleAttachRootWidget.<anonymous closure>
package:flutter/…/widgets/binding.dart:908
(elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)
for (int i; i < recentTransactions.length; i++) {
This is the part causing the Error, since it is stated: "The method '<' was called on null." You have to initalise your int i = 0, so the code should look like
for (int i = 0; i < recentTransactions.length; i++) {

Flutter plugin just_audio example error then dispose

I've just copied the example of just_audio library and put in into my project, and then I'm doing a hot reload or pressing back, I'm getting an error
[VERBOSE-2:shell.cc(209)] Dart Error: Unhandled exception:
Bad state: You cannot close the subject while items are being added from addStream
#0 Subject.close (package:rxdart/src/subjects/subject.dart:152:7)
#1 AudioPlayer.dispose (package:just_audio/just_audio.dart:611:30)
<asynchronous suspension>
#2 _LessonPractiseScreenState.dispose (package:wbh/ui/pages/lesson/lesson_practise_screen.dart:90:13)
#3 StatefulElement.unmount (package:flutter/src/widgets/framework.dart:4773:12)
#4 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1935:13)
#5 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1933:7)
#6 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:4600:14)
#7 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1931:13)
#8 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1933:7)
#9 SingleChildRenderObjec<…>
The causing widget as I tested is:
Widget get _seekBar => StreamBuilder<Duration>(
stream: _player.durationStream,
builder: (context, snapshot) {
final duration = snapshot.data ?? Duration.zero;
return StreamBuilder<Duration>(
stream: _player.positionStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
var position = snapshot.data ?? Duration.zero;
if (position > duration) {
position = duration;
}
return SeekBar(
duration: duration,
position: position,
onChanged: (newPosition) {
_player.seek(newPosition);
},
);
} else
return Container();
},
);
},
);
But I can't fix it by myself and have got no info on the net, so will appreciate any help.
This was reported as a bug via GitHub and a fix was rolled out soon after (see this issue for the discussion). Newer releases (>= 0.4.4) should resolve this issue.