How do you patch a method in a class and then assert that that patched method was only called once?
For example:
import typing
import unittest
import unittest.mock
class Example:
def __init__(self: "Example") -> None:
self._loaded : bool = False
self._data : typing.Union[str,None] = None
def data(self: "Example") -> str:
if not self._loaded:
self.load()
return self._data
def load(self: "Example") -> None:
self._loaded = True
# some expensive computations
self._data = "real_data"
def mocked_load(self: "Example") -> None:
# mock the side effects of load without the expensive computation.
self._loaded = True
self._data = "test_data"
class TestExample( unittest.TestCase ):
def test_load(self: "TestExample") -> None:
# tests for the expensive computations
...
@unittest.mock.patch("__main__.Example.load", new=mocked_load)
def test_data(
self: "TestExample",
# patched_mocked_load: unittest.mock.Mock
) -> None:
example = Example()
data1 = example.data()
self.assertEqual(data1, "test_data")
# example.load.assert_called_once()
# Example.load.assert_called_once()
# mocked_load.assert_called_once()
# patched_mocked_load.assert_called_once()
data2 = example.data()
self.assertEqual(data2, "test_data")
# Should still only have loaded once.
# example.load.assert_called_once()
# Example.load.assert_called_once()
# mocked_load.assert_called_once()
# patched_mocked_load.assert_called_once()
if __name__ == '__main__':
unittest.main()
How in the test_data
unit test do I assert that the patched load
function was only called once?
The problem is that you substitute load
with your own function, which is not a mock and therefore does not have assert_called_xxx
methods.
You need to substitute it with a mock and add the wanted behavior to the mock instead:
@unittest.mock.patch("__main__.Example.load")
def test_data(
self: "TestExample",
patched_mocked_load: unittest.mock.Mock
) -> None:
example = Example()
patched_mocked_load.side_effect = lambda: mocked_load(example)
data1 = example.data()
self.assertEqual(data1, "test_data")
patched_mocked_load.assert_called_once()
data2 = example.data()
self.assertEqual(data2, "test_data")
patched_mocked_load.assert_called_once()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.