Mocking two functions with patch for a unit test
mocking, nose, python, testing, unit-testing
Solution
You can simplify your test by using the patch decorator and nesting them like so (they are `MagicMock` objects by default):
from unittest.mock import patch
@patch('cPickle.dump')
@patch('__builtin__.open')
def test_write_out(mock_open, mock_pickle):
path = '~/collection'
f = mock_open.return_value
f.method.return_value = path
write_out(path, 'data')
mock_open.assert_called_once_with('~/collection', 'wb')
mock_pickle.assert_called_once_with('data', f)
f.close.assert_any_call()
Calls to a `MagicMock` instance return a new `MagicMock` instance, so you can check that the returned value was called just like any other mocked object. In this case `f` is a `MagicMock` named `'open()'` (try printing `f`).
Problem
I have a function I want to unit test contains calls two other functions. I am unsure how can I mock both functions at the same time properly using patch. I have provided an example of what I mean below. When I run nosetests, the tests pass but I feel that there must be a cleaner way to do this and I do not really Understand the piece regarding f.close()... The directory structure looks like this: ``` program/ program/ data.py tests/ data_test.py ``` data.py: ``` import cPickle def write_out(file_path, data): f = open(file_path, 'wb') cPickle.dump(data, f) f.close() ``` data_test.py: ``` from mock import MagicMock, patch def test_write_out(): path = '~/collection' mock_open = MagicMock() mock_pickle = MagicMock() f_mock = MagicMock() with patch('__builtin__.open', mock_open): f = mock_open.return_value f.method.return_value = path with patch('cPickle.dump', mock_pickle): write_out(path, 'data') mock_open.assert_called_once_with('~/collection', 'wb') f.close.assert_any_call() mock_pickle.assert_called_once_with('data', f) ``` Results: ``` $ nosetests . ---------------------------------------------------------------------- Ran 1 test in 0.008s OK ```