3. unittest.mock
Defn: unittest.mock is a library for testing in Python. It
allows you to replace parts of your system under test with
mock objects and make assertions about how they have
been used.
• Using Mock you can replace/mock any dependency of
your code.
• Unreliable or expensive parts of code are mocked using
Mock, e.g. Networks, Intensive calculations, posting on
a website, system calls, etc.
4. • As a developer you want your calls to be right
rather than going all the way to final output.
• So to speed up your automated unit-tests you
need to keep out slow code from your test runs.
6. >>> from unittest.mock import Mock
>>> m = Mock()
>>> m
<Mock id='140457934010912'>
>>> m.some_value = 23
>>> m.some_value
23
>>> m.other_value
<Mock name='mock.other_value' id='140457789462008'>
Mock Objects - Basics
7. >>> m.get_value(value=42)
<Mock name='mock.get_value()' id='140457789504816'>
>>> m.get_value.assert_called_once_with(value=42)
>>> m.get_value.assert_called_once_with(value=2)
raise AssertionError(_error_message()) from cause
AssertionError: Expected call: get_value(value=2)
Actual call: get_value(value=42)
8. • Flexible objects that can replace any part of
code.
• Creates attributes when accessed.
• Records how objects are being accessed.
• Using this history of object access you can make
assertions about objects.
More about Mock objects
10. Using spec to define attr
>>> user_info = ['first_name', 'last_name', 'email']
>>> m = Mock(spec=user_info)
>>> m.first_name
<Mock name='mock.first_name' id='140032117032552'>
>>> m.address
raise AttributeError("Mock object has no attribute %
r" % name)
AttributeError: Mock object has no attribute 'address'
11. Automatically create all specs
>>> from unittest.mock import create_autospec
>>> import os
>>> m = create_autospec(os)
>>> m.
Display all 325 possibilities? (y or n)
m.CLD_CONTINUED m.forkpty
m.CLD_DUMPED m.fpathconf
m.CLD_EXITED m.fsdecode
[CUT]
m.fchown m.walk
m.fdatasync m.write
m.fdopen m.writev
m.fork
12. Using Mock through patch
• Replaces a named object with Mock object
• Also can be used as decorator/context manager
that handles patching module and class level
attributes within the scope of a test.
16. patching methods #2
>>> with patch.object(os, 'listdir', return_value=
['abc.txt']) as mock_method:
... a = os.listdir('/home/hummer')
...
>>> mock_method.assert_called_once_with
('/home/hummer')
>>>
17. Mock return_value
>>> m = Mock()
>>> m.return_value = 'some random value 4'
>>> m()
'some random value 4'
OR
>>> m = Mock(return_value=3)
>>> m.return_value
3
>>> m()
3
18. Mock side_effect
• This can be a Exception, Iterable or function.
• If you pass in a function it will be called with
same arguments as the mock, unless function
returns DEFAULT singleton.
19. #1 side_effect for Exception
>>> m = Mock()
>>> m.side_effect = ValueError('You are always gonna get this!!')
>>> m()
raise effect
ValueError: You are always gonna get this!!
24. What is pytest?
● A fully featured Python Testing tool.
● Do automated tests.
25. Tests with less Boilerplate
1 import unittest
2
3 def cube(number):
4 return number ** 3
5
6
7 class Testing(unittest.TestCase):
8 def test_cube(self):
9 assert cube(2) == 8
Before py.test
26. 1 def cube(number):
2 return number ** 3
3
4 def test_cube():
5 assert cube(2) == 8
6
7 # Here no imports or no classes are needed
After py.test
27. Running Tests
pytest will run all files in the current directory and
its subdirectories of the form test_*.py or
*_test.py or else you can always feed one file at a
time.
$ py.test cube.py
=============================== test session starts============================================
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
rootdir: /home/hummer/Study/Nov2015PythonPune/pyt, inifile:
collected 1 items
cube.py .
===============================1 passed in 0.01 seconds========================================
28. $ py.test
Run entire test suite
$ py.test test_bar.py
Run all tests in a specific file
$ py.test -k test_foo
Run all the tests that are named test_foo
By default pytest discovers tests in
test_*.py and *_test.py
29. pytest fixtures
• Fixtures are implemented in modular manner, as each
fixture triggers a function call which in turn can trigger
other fixtures.
• Fixtures scales from simple unit tests to complex
functional test.
• Fixtures can be reused across class, module or test
session scope.