Mocking with Python - Part II
Kiran Koduru • Nov 15, 2017 • 5 minutes to readThis is part 2 of my mocking with python blog series. If you haven’t read the first part or have, and would like to skim over the basics, then please go ahead and read it (again). Both articles aren’t in any way an expert guide but my personal quest on learning python mocking. I’ll try my best to convey my thoughts and try to cover all topics related to Python mock.
Mocking helps me runs local tests quickly. Another place where mocking helps is in continuous integration environments. When a whole team of developers that work on a same project, you want to quickly verify the new changes look okay. Mocking allows for faster test run times on CI servers as well. I wouldn’t consider this as a replacement for running integration test but a first pass on testing with mocks is ok.
Are my mocks called?
When testing with mocks, how do I know if my mocked object is being called? The python mocking library comes with assert
methods that will help you run test mocked objects. I’ll highlight the called
and assert_called_with
attributes with an example below. But you can also use similar logic for assert_called
, assert_called_once
, assert_called_once_with
, assert_any_call
and assert_has_calls
methods.
Let’s test with a function called sum_numbers_add_random_int
, where I add a random
integer to the sum of list
of numbers. This function randomly selects a number between 1 and 100 to add to the sum of numbers. For example, I have a list
of numbers [1, 2, 3]
whose sum is 6
. I will randomly add an integer between 1-100 to 6
, which could result into any number from 7-106 being returned by sum_numbers_add_random_int
.
To test the random_sum.py file I will mock the random
library’s randint
function. I do this cause I can’t predict the return value for randint
. I replace the return_value
for randint
with 1, 2 and 3. This sould return a sum of 34, 35 and 36 when the sum_numbers_add_random_int
function is called.
Mocking Functions
In the same way I can patch functions in python as well. I will demonstrate with two functions add_two_numbers
and print_text
in a file adding_two_nums. The add_two_numbers
returns the sum of it’s parameters number1
and number2
but prints the sum before returning it.
In my test case I patch the print_text
method, whose only purpose in life is to print any given text. You could use this idea to patch any function’s return value with mock. Just make sure to test if they are called correctly.
Hope this post gave you an idea on how and where to mock your functions. In my next post on mocking with python series I will discuss how to mock/test exceptions, iterables and other side effects. If you’d like to stay updated, do signup to my newsletter.
I am writing a book!
While I do appreciate you reading my blog posts, I would like to draw your attention to another project of mine. I have slowly begun to write a book on how to build web scrapers with python. I go over topics on how to start with scrapy and end with building large scale automated scraping systems.
If you are looking to build web scrapers at scale or just receiving more anecdotes on python then please signup to the email list below.