Here is a tutorial on how to create mocks with the mockito package, set them up, and use them in your tests of a Flutter application.
During testing, there will always be a point where you need a mock. This mock will save you from setting up complex environments for a test because it allows you to focus on the parts you want to test. Assume you have a logger in multiple places in your application that writes into a database. Of course, you have tests for your logger to ensure its correct functionality. But when you test, for example, your login mechanism, you don’t care about the logger. That’s where a mock is useful. It handles the calls to the logger and reacts the way it was configured.
In this guide, we are looking at the Mockito package for Flutter apps. It allows you to create mocks so that any dependencies of your classes don’t need to be handled for testing.
The class to test
Here is the
DataService class, we are going to write tests for. It takes a
DataStore object as a constructor argument. The
DataStore could be anything from a remote database over the local storage on the device to a simple
Map<string, dynamic>() object that stores the values. We don’t want to deal with this dependency, so we are going to mock it in our test.
Generate the mock
The build runner tool of Dart helps us to create mocks for every class we want. We add it to our Flutter app with the command
flutter pub add build_runner. Afterward, we specify the classes for which a mock should be generated. We add an annotation at the
main() method of our empty test class (see code below).
And finally, we call the build runner with
flutter pub run build_runner build. It will create a new class that contains all mocks specified in the array of the annotation.
Using the mock in tests
To test the
get() method, we need to set up the mock. Otherwise, an exception will be thrown, because since Dart 2.12/Flutter 2 and Null Safety there isn’t a common default value like
null that could be returned.
To specify the behaviour, we use the
thenAnswer() methods. You can see it in the image below.
get() method of the mock is called, it always answers with a fixed value that we can verify afterward. Additionally, we can ask the mock if the
get() method was called to be more confident.
If you want your mocks to return null when there is no setup available, then use replace your annotation
@GenerateMocks(,customMocks: [MockSpec<DataStore>(returnNullOnMissingStub: true)])
Then your test could look like this
You can find the source code on GitHub.