Mock, My Hero for Unittesting
Perhaps, If you met a dead end when creating testing, maybe you need to read this article
This article was written as an individual review assignment for PPL CSUI 2021
As the bottom line, Testing is a must!. So no matter what tools we use, what services we use, we have to find a way to test our code. but why? because if we did not write a test, we just like people who walk blindfolded, we don’t know what is coming in front of us. even if we do write a test, we still occasionally found bugs and errors in production that we have to cold fix. so like it or not, Testing is a must!
Even I said testing is a must, there are many cases that programmable test like unittest is almost impossible to be done, and we need another approach of testing such as functional testing, integration testing and also QA. So the conclusion is testing is important, but coverage is important if we are using unittesting.
Okay okay, so we have to write a test, but have you ever feel stuck when you are writing a test that also dependent on third-party services? especially if we have to do some further authentication to utilize that services, or maybe we will write some data into that services but you think it would be not a great idea if we repeatedly use that services just for testing because it would be spammed the databases or will cost us lot of money? In my personal experience this problem became a headache for me for a long time because I don’t know how to resolve this problem, but one day, I found my hero….
Let me introduce the hero…. “MOCK” to the rescue
So what is Mock exactly? In my personal opinion, mock or mocking is a concept of “mocking" something as a BlackBox that we gave this BlackBox an input and we don’t care how the BlackBox works, but we can expect the result or output, then we use the output for other businesses. well my opinion about mocking maybe not 100% accurate, but let me gave you an example.
Imagine you are using a mailing service such as Gmail for your projects to send an email for your users, then, in your project, you are using this services to send an email to the new users after you are creating a new account for them, and the user creation flow is entirely your own code and not using any third-party dependencies. So we have to test this feature right? but we found an obstacle which is we can’t test this feature because we can’t use test data for sending email, and if we use test data, the feature can’t work as it has to be done. So to resolve this problem, we mock the mail service, we can assume mail service is just a BlackBox that will give us an output that we want, without worry the mail service gave us an error, because we already defined the output from this mocked BlackBox. and if we doing this mock test, we can test our own code which is the creation of new users without worry about how to send an email when we just doing a test.
How I implement mocking in my PPL Projects
In my projects cases, the cases might be similar to the example I gave before, but instead of just using Gmail, I am also using firebase services, which is consist of auth and firestore. so in my case, I have to create a new account into my firebase auth, then after that, I need to save some metadata about this account into firestore, after this process finish, I will send an email to this newly created user an email consist of their email and password that can be used for login. it’s cleary we need further authentication process into the firebase auth and firestore and also I have to programmatically login to gmail account so I can send an email. Well, if I am doing a unittest for this feature without mocking, I think it's almost impossible, and if it’s possible, we will get a side-effect which is spam data in our firebase auth and our firestore. so to test this, I am using mock. in my project I was using python with flask, so for the testing tools, I am using pytest and unittest library for mocking.
The above code snippet is the function/endpoint that I have to test, and I will mock create_user(data) function because this function is the function that using third-party dependencies that I already talked about before.
as you can see, create_user function are using firestore db, firebase auth and also send email. so I will mock this function. For mocking this function, I am using patch class that already provided in unittest library, you can learn more about patch in their documentation.
just like what I said, I mock the create_user function as mock_create_user and I expect this BlackBox an output which is a tuple with message and status code. and because I already mocking this function, I will not need to worry about how to access my firestore or firebase project or even login to my Gmail because all of these services are have been mocked
even I did not talk too much about how to use unittest mock in python, but for me, the game-changer is when we find out the idea behind mock itself because unittest library is just a tool and the important thing is we know the concept of mocking. So when you find a dead end when you are writing a test for your code, I hope this article about what is mocking could make you resolved your problems
I think that's all from me for this article, hope you enjoy it, and don’t forget to sleep, folks! :D
Mocking External APIs in Python - Real Python
The following tutorial demonstrates how to test the use of an external API using Python mock objects. Integrating with…