Skip to content

Testing

Bloc was designed to be extremely easy to test. In this section, we’ll walk through how to unit test a bloc.

For the sake of simplicity, let’s write tests for the CounterBloc we created in Core Concepts.

To recap, the CounterBloc implementation looks like:

counter_bloc.dart
sealed class CounterEvent {}
final class CounterIncrementPressed extends CounterEvent {}
final class CounterDecrementPressed extends CounterEvent {}
class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc() : super(0) {
on<CounterIncrementPressed>((event, emit) => emit(state + 1));
on<CounterDecrementPressed>((event, emit) => emit(state - 1));
}
}

Setup

Before we start writing our tests we’re going to need to add a testing framework to our dependencies.

We need to add test and bloc_test to our project.

Terminal window
dart pub add dev:test dev:bloc_test

Testing

Let’s get started by creating the file for our CounterBloc Tests, counter_bloc_test.dart and importing the test package.

counter_bloc_test.dart
import 'package:test/test.dart';
import 'package:bloc_test/bloc_test.dart';

Next, we need to create our main as well as our test group.

counter_bloc_test.dart
void main() {
group(CounterBloc, () {
});
}

Let’s start by creating an instance of our CounterBloc which will be used across all of our tests.

counter_bloc_test.dart
group(CounterBloc, () {
late CounterBloc counterBloc;
setUp(() {
counterBloc = CounterBloc();
});
});

Now we can start writing our individual tests.

counter_bloc_test.dart
group(CounterBloc, () {
late CounterBloc counterBloc;
setUp(() {
counterBloc = CounterBloc();
});
test('initial state is 0', () {
expect(counterBloc.state, equals(0));
});
});

At this point we should have our first passing test! Now let’s write a more complex test using the bloc_test package.

counter_bloc_test.dart
blocTest(
'emits [1] when CounterIncrementPressed is added',
build: () => counterBloc,
act: (bloc) => bloc.add(CounterIncrementPressed()),
expect: () => [1],
);
blocTest(
'emits [-1] when CounterDecrementPressed is added',
build: () => counterBloc,
act: (bloc) => bloc.add(CounterDecrementPressed()),
expect: () => [-1],
);

We should be able to run the tests and see that all are passing.

That’s all there is to it, testing should be a breeze and we should feel confident when making changes and refactoring our code.

You can refer to the Weather App for an example of a fully tested application.