My Adventures in Coding

February 26, 2011

Python – Getting Started with Python Mock

Filed under: Python,Testing — Brian @ 12:00 am
Tags: , , ,

These examples all use the Python Mock library. This post is just a quick “Getting Started” for someone who is new to using the Python Mock library, once you get started refer to the Python Mock Documentation.

First you will need to install the mock library:

pip install -U mock

Your test file will need the following import statement:

from mock import patch, Mock

To mock a method in a class to return a specific value use @patch.object.

@patch.object(my_module.MyClass, 'my_method')
def test_my_method_shouldReturnTrue_whenMyMethodReturnsSomeValue(self, mock_my_method):
    mock_my_method.return_value=True
    some_other_class =  SomeOtherClassThatUsesMyClass()
    result = some_other_class.method_under_test()
    self.assertTrue(result)

To mock a method in a class with @patch.object but return a different value each time it is called, use side_effect. Side effect allows you to define a custom method and have that method called each time your mock method is called. The value returned from this method will be used as the return value your mock method.

@patch.object(my_module.MyClass, 'my_method')
def test_my_method_shouldReturnMultipleValues_whenMyMethodReturnsSomeValue(self, mock_my_method):
    list_of_return_values= [True,False,False]
    def side_effect():
        return list_of_return_values.pop()
    mock_my_method.side_effect = side_effect
    some_other_class =  SomeOtherClassThatUsesMyClass()
    self.assertFalse(some_other_class.method_under_test())
    self.assertFalse(some_other_class.method_under_test())
    self.assertTrue(some_other_class.method_under_test())

To mock an entire class to test interactions with that class use @patch.

@patch('my_module.MyClass')
def test_my_method_shouldCallMyClassMethodMyMethod_whenSomeOtherClassMethodIsCalled(self, mock_my_class):
    some_other_class =  SomeOtherClassThatUsesMyClass()
    some_other_class.method_under_test()
    self.assertTrue(mock_my_class.called)

To mock an entire class with @patch and still set the return value of a method in that class, grab the instance of the mock object’s return value and set the method’s return value on the instance. There is a section on the patch page explaining how to do this.

@patch('my_module.MyClass')
def test_my_method_shouldReturnTrue_whenSomeOtherClassMethodIsCalledAndAReturnValueIsSet(self, mock_my_class):
    mc = mock_my_class.return_value
    mc.my_method.return_value = True
    some_other_class =  SomeOtherClassThatUsesMyClass()
    result = some_other_class.method_under_test()
    self.assertTrue(result)

Finally, here is the simple code I used as my “code under test” to write these example tests:

class MyClass():
    def my_method(self):
        pass

class SomeOtherClassThatUsesMyClass():
    def method_under_test(self):
        myclass = MyClass()
        return myclass.my_method()

There are many other features in the Python Mock library, but these are the basics that will help you get started!

About these ads

4 Comments »

  1. Thanks, this helped by getting to the point, unlike the official documentation!

    Comment by NA. — September 7, 2011 @ 10:06 pm | Reply

    • Great! I am glad you found the post useful!

      Comment by Brian — September 8, 2011 @ 1:15 am | Reply

  2. [...] Python Mock Cheat Sheet [...]

    Pingback by Unit Testing: Necessary and Sufficient — November 30, 2012 @ 10:29 pm | Reply

  3. @patch.object(my_module.MyClass, ‘my_method’)

    Using this in Test case throws an error ‘Undefined variable’ that it can not find that module
    Also,my_method throws an error that it can not Undefined variable: my_method

    Comment by anujacharya — December 21, 2012 @ 12:44 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 27 other followers

%d bloggers like this: