I'm trying to run the following test using pytest and pytest_mock
def rm(filename):
helper(filename, 5)
def helper(filename):
pass
def test_unix_fs(mocker):
mocker.patch('module.helper')
rm('file')
helper.assert_called_once_with('file', 5)
But I get exception AttributeError: 'function' object has no attribute 'assert_called_once_with'
What am I doing wrong?
side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT , the return value of this function is used as the return value.
This, along with its subclasses, will meet most Python mocking needs that you will face in your tests. The library also provides a function, called patch() , which replaces the real objects in your code with Mock instances.
To begin with, MagicMock is a subclass of Mock . class MagicMock(MagicMixin, Mock) As a result, MagicMock provides everything that Mock provides and more. Rather than thinking of Mock as being a stripped down version of MagicMock, think of MagicMock as an extended version of Mock.
You can not perform a .assert_called_once_with
function on a vanilla function: you first need to wrap it with the mock.create_autospec
decorator. So for instance:
import unittest.mock as mock
def rm(filename):
helper(filename, 5)
def helper(filename):
pass
helper = mock.create_autospec(helper)
def test_unix_fs(mocker):
mocker.patch('module.helper')
rm('file')
helper.assert_called_once_with('file', 5)
Or more elegantly:
import unittest.mock as mock
def rm(filename):
helper(filename, 5)
@mock.create_autospec
def helper(filename):
pass
def test_unix_fs(mocker):
mocker.patch('module.helper')
rm('file')
helper.assert_called_once_with('file', 5)
Note that the assertion will fail, since you call it only with 'file'
. So a valid test would be:
import unittest.mock as mock
def rm(filename):
helper(filename, 5)
@mock.create_autospec
def helper(filename):
pass
def test_unix_fs(mocker):
mocker.patch('module.helper')
rm('file')
helper.assert_called_once_with('file')
EDIT: In case the function is defined in some module, you can wrap it in a decorator locally. For example:
import unittest.mock as mock
from some_module import some_function
some_function = mock.create_autospec(some_function)
def test_unix_fs(mocker):
some_function('file')
some_function.assert_called_once_with('file')
In oriented object case:
class Foo:
def rm(self, filename):
self.helper(filename, 5)
def helper(self, filename, number):
pass
def test_unix_fs(mocker):
mocker.patch.object(Foo, 'helper')
foo = Foo()
foo.rm('file')
helper.assert_called_once_with('file', 5)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With