Mocking tests with mocktail in Flutter
Hello dev, if you already had to mock some data in order to test your code you know that sometimes it can be struggling but there are some packages that can help you with that.
One of them is mocktail which is pretty easy and good to use, so in this article I want to show a little bit how to use it.
Basically I’m creating this project with just a simple http call and using a standard state management, and if you want to see the code I’ll let the link here.
And as you can see I just added these packages in the pubspec.yaml as the image bellow.
Now here comes the tests, and the first thing I want to test is the repository class which has the backend call. And if you had never written a test before, one basic trick is first mount the mock data and all the pre sets needed.
And for that mocktail comes to help, because I needed to mock the dio package instead of depends on internet connection.
And to do that you just have to create a class, extends the Mock class and also implements the one you want to have as mock. So with that I can pass the instance through the constructor of the repository.
Now is time to mock the response with the expected json, and for that you just need to say when you call the backend with any url the answer is going to be the response with the jsonMock, so now you can execute the desired method on the repository.
And last but not least, is the check to see if all execution gives you the expect result.
Ok, so now it’s time to test the state management to see if it can communicate with the repository and store the expected value.
So basically the steps are pretty much the same, but this time the mock is the repository it self.
In this project I’m using the ValueNotifier and to test this I needed to listen to all changes simulating the states that I’ve created, so I added in the setUp method a listener because this method will be executed before the tests.
Once more I created the when condition, but this time with the list of expected objects as the answer, and then I added a bunch of expect to test if all the states are being set.
And with all that you can simply run the “flutter test” command in the terminal to see if all the tests passed. But let’s give one step forward, let’s see the coverage of the tests, because I it’s really important to see if all the application is being tested.
For that run the command “flutter test --coverage”, and you will see that the coverage folder was created in the root of the project. But the generated file is not friendly to read right? So let’s install something to help us reading this.
I’m using a macOS and I used the brew to install the lcov tool, and if you are using a different operating system try to see how to install this tool.
After doing it run the command “genhtml coverage/lcov.info -- output=coverage”, to generate a html file with the coverage result, but note that in your case the coverage can be different.
Because if you are using a code generation to create your models and that stuff, you can exclude it from the coverage using this command “lcov --remove coverage/lcov.info ‘lib/*.g.dart’ -o coverage/lcov.info”.
And one thing that I discovered latter is, if you are using the freezed package to generate your classes, the const constructor is not consider tested for some reason, so I had to exclude it from the coverage with the “// coverage:ignore-line”. Oh, by the way I read about it in this link.
And that’s it, use all these tools to make your project quality increase with tests can be also one of the keys to make your app quality better than ever.