Flutter - Expected: should do the following in order: emits an event Empty, NumberTriviaError, Actual: Empty: Which was not a Stream or a SteamQue

Viewed 747

I'm doing Flutter Clean Architecture TDD course from closely 20days. I'm writing unit test of Stream (mapEventToState) here is my Test code :

test(
  'should emit [Error] when the input is invalid',
      () async {
    // arrange
    when(mockInputConverter!.stringToUnsignedInteger(SIGNED_STRINGS))
        .thenReturn(Left(InvalidInputFailure()));
    // assert later
    final expected = [
      // The initial state is always emitted first
      NumberTriviaEmpty(),
      NumberTriviaError(message: INVALID_INPUT_FAILURE_MESSAGE),
    ];
    expectLater(bloc!.state, emitsInOrder(expected));
    // act
    bloc!.add(GetTriviaForConcreteNumber(tNumberString));
  },
);

Just forget all about (when), because It's fine I've mocked all classes and simply return a Left of Either which is obviously a Failure. So the problem rise in expected data, I just created list of expected and passed it inside the method the "expectLater" in order "emitsInOrder".

My Implementation code of Stream is is here :

@override
Stream<NumberTriviaState> mapEventToState(NumberTriviaEvent event,) async* {
if (event is GetTriviaForConcreteNumber) {
  final inputEither =
  inputConverter.stringToUnsignedInteger(event.numberString);

  yield* inputEither!.fold(
        (failure) async* {
      yield NumberTriviaError(message: INVALID_INPUT_FAILURE_MESSAGE);
    },
    // Although the "success case" doesn't interest us with the current test,
    // we still have to handle it somehow.
        (integer) => throw UnimplementedError(),
  );
}

The [ Error ] I have put in the Title isn't completed because It's a little bit long I'm sharing it here please take a look upon It what actually I'm doing wrong.

Expected: should do the following in order:
      • emit an event that NumberTriviaEmpty:<NumberTriviaEmpty()>
      • emit an event that NumberTriviaError:<NumberTriviaError(Invalid Input - The number must be a positive integer or zero.)>
 Actual: NumberTriviaEmpty:<NumberTriviaEmpty()>
 Which: was not a Stream or a StreamQueue

I have done all these the same, what it expect from me but still it's throwing this exception. I stuck in this error about 4 days I search everywhere but I didn't find any fix, Kindly If I'm doing something wrong just throw your recommendation in the comment section or Answer. Thank you :)

4 Answers

In addition to changing 'bloc!.state' to 'bloc' (per QuangNV and ouflak), try also changing the 'async' in your test to the asynchronous generator, 'async*', to match to the code used in your Stream implementation.

test(
  'should emit [Error] when the input is invalid',
      () async* {
    // arrange

So the complete answer is

You can try changing from:

expectLater(bloc!.state, emitsInOrder(expected));

To:

expectLater(bloc, emitsInOrder(expected));

In addition to changing 'bloc!.state' to 'bloc' (per QuangNV and ouflak), try also changing the 'async' in your test to the asynchronous generator, 'async*', to match to the code used in your Stream implementation.

test(
  'should emit [Error] when the input is invalid',
      () async* {
// arrange

You can try changing from:

 expectLater(bloc!.state, emitsInOrder(expected));

To:

 expectLater(bloc, emitsInOrder(expected));

Hope you can solve it!

I used another way by using the bloc_test: ^8.0.0 package and the flutter_bloc: ^7.0.0

  blocTest<NumberTriviaBloc, NumberTriviaState>(
    'should emits [LoadingState, ErrorState(InputConvert failure..)] when add event [getConcreteNumberTrivia] with invaildString ',
    build: () => numberTriviaBloc,
    setUp: () => when(mockInputConverter.stringToUnsignedInteger(any))
        .thenReturn(const Left(InvalidInputFailure())),
    act: (bloc) =>
        bloc.add(const GetConcreteNumberEvent(number: tNumberString)),
    expect: () => [
      LoadingState(),
      ErrorState(message: const InvalidInputFailure().message)
    ],
  );
Related