Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Mock() in Python

Can you give some clear examples of uses of the Mock() in Django unittests? I want to understand it more clearly.

Update: I've figured out some things, so I share it below.

like image 373
Kee Avatar asked Sep 26 '11 13:09

Kee


2 Answers

Part 1: Basics

from mock import Mock

Mock object is an object that is a kind of a Dummy for the code that we want not to be executed, but for which we want to know some information (number of calls, call arguments). Also we might want to specify a return value for that code.

Let us define simple function:

def foo(value):
    return value + value

Now we're ready to create a Mock object for it:

mock_foo = Mock(foo, return_value='mock return value')

Now we can check it:

>>> foo(1)
2
>>> mock_foo(1)
'mock return value'

And get some information on calls:

>>> mock_foo.called
True
>>> mock_foo.call_count
1
>>> mock_foo.call_args
((1,), {})

Available attributes of Mock() instance are:

call_args       func_code       func_name
call_args_list  func_defaults   method_calls
call_count      func_dict       side_effect
called          func_doc        
func_closure    func_globals    

They're quite self-explanatory.

Part 2: @patch decorator

The @patch decorator allows us to easily create mock objects for imported objects (classes or methods). It is very useful while writing unit-tests.

Let us assume that we have following module foo.py:

class Foo(object):
    def foo(value):
        return value + value

Let us write a test for @patch decorator. We are going to patch method foo in class Foo from module foo. Do not forget imports.

from mock import patch
import foo

@patch('foo.Foo.foo')
def test(mock_foo):
    # We assign return value to the mock object
    mock_foo.return_value = 'mock return value'
    f = foo.Foo()
    return f.foo(1)

Now run it:

>>> test()
'mock return value'

Voila! Our method successfully overridden.

like image 191
Kee Avatar answered Oct 29 '22 16:10

Kee


The Mock site has some really nice API documentation that cover all of this. Note that patch replaces all instances of foo.Foo.foo where ever they are called. It is not the preferred way to mock something but can be the only way -- see open().

like image 21
Sardathrion - against SE abuse Avatar answered Oct 29 '22 16:10

Sardathrion - against SE abuse