60 Days of Flutter :Building a Messenger : Day 51–54 : Unit Testing Firebase Providers with Mockito

Aditya Gurjar
6 min readOct 11, 2019

--

So I’ve been doing Unit Testing for the last one week and here’s what I think.

It’s more important than most people think it is. It is one of the earliest testing efforts performed on the code and the earlier defects are detected, the easier they are to fix.

It’s often the most avoided part of the entire SDLC, especially for small scale applications. Which is fine sometimes when the application is really small and is just a prototype but in other cases one should try to write as much tests as possible. This is how lot of developers react when they’re asked about tests.

This does not necessarily mean that you have to aim for 100% code coverage because let’s be real, that’s hard to achieve and might not be necessary in most cases. So try to test every part of the code which you feel that isn’t very basic or might break someday.

But How Do I Approach Testing?

For many beginners the biggest question is that how do I start writing tests? what exactly do they do? So in the most basic words,

A Unit Test is meant to check the behavior of the particular class/function by providing it a set of inputs and confirming that

  • the execution flow is what we expected it to be.
  • and the result is what we expect it to be.

Unit Testing the Providers

We’re using Firebase and I/O related stuff in all of our providers and so we need a way to mock them in our test environment. It’s a simple exercise and the easiest way to do it is,

  • look at the function you’re testing, line by line,
  • mock everything which needs to be mocked.
  • connect the dots (link the behaviors of mock objects).

Let me show you how with a quick example.

We have a method in our ChatProvider called getAttachments. This method returns all the attachments of a particular type (1:Image, 2: Video, 3: File) for a particular Chat.

Let’s write the test for it.

  • First call is to FireStore that means we need to create a mock FireStore instance (FirestoreMock is created using mockito. Check this post to see how).
  • fireStore.collection(Paths.chatsPath) should return a collection.
  • A document(chatId) call on this collection should give us the DocumentReference.
  • chatDocRef.collection(Paths.messagesPath) will return a CollectionReference.
  • Whenever we call any query on this messagesCollection it will return us with a Query object. We have three queries in our query chain and we mock them like this:

Now you might be wondering why I’m returning the same object again and again? It’s because of one simple principle:

Always test your business logic (code) and not the functionality of the framework.

In this case the query functions are part of the Firebase Package and we can depend on them(the framework) to work properly. What we do need to make sure that the where and the orderBy queries are always part of the function call. So that the end result isn’t faulty. So we just simply create a mock query object and pass it till the end of the chain.

Lets remove

when(query.orderBy('timeStamp', descending: true)).thenReturn(query);

and this is what happens:

The chain is broken and so the tests fails. Pretty handy in case someone accidentally modify/delete the line!

  • Next we mock the final message documents. (messageDataMock is part of DataMock.dart. Check Code Changes section to see it).
  • And in the final step we call the getAttachments method for the chatId and the fileType we mocked above, and then verify that all the mocked results are of type ImageMessage .

Run the tests and I bet seeing this message will make you feel like writing more and more tests.

This is just one test. I’ve written tests for all the Providers. Check out the code in their respective gists:

And this will be it for the day. Do check the code changes section for the data objects I’ve created for mocking. In the next post we’ll touch upon Firebase Database rules.

Code Changes

#40 Added tests for all the providers

How Can You Contribute?

Posts In This Series

Show Your Support

Press the clap button below if you liked reading this post. The more you clap the more it motivates me to write better!

--

--

Aditya Gurjar

Mobile Engineer. Writing Mostly about Mobile Dev, Mobile DevOps, and a lil bit of life.