I'm trying to test a class and mock one of its methods, but I can't seem to replace the behavior of one of the instance methods with my mocked behavior. My code is organized like so:
--src ----module ------__init__.py ------my_class.py --tst ----__init__.py ----test_my_class.py
my_class.py
contains the following
class MyClass:
def __init__(self):
pass
def do_something(self):
return 'Real Output'
My test file test_my_class.py
contains the following.
from unittest.mock import patch
from src.module.my_class import MyClass
def test_my_class():
my_class = MyClass()
assert my_class.do_something() == 'Real Output'
@patch('src.module.my_class.MyClass')
def test_mock_my_class(mock_my_class):
mock_my_class.return_value.do_something.return_value = 'Mocked Output'
my_class = MyClass()
assert my_class.do_something() == 'Mocked Output'
The first test works just fine (no mocking involved so far). The second test, however, gives me the following assertion error. I expect the do_something()
method to be mocked and to return "Mocked Output", and for the assert statement to evaluate to true. Where am I going wrong here?
AssertionError: assert <bound method MyClass.do_something of <src.module.my_class.MyClass object at 0x1057133c8>> == 'Mocked Output' E + where <bound method MyClass.do_something of <src.module.my_class.MyClass object at 0x1057133c8>> = <src.module.my_class.MyClass object at 0x1057133c8>.do_something
PS. I've consulted the following resources without success:
That last link looked especially helpful at first, because I'm following one of the examples almost verbatim, but it still doesn't work.
@mock.patch("simple.SimpleClass")
def mock_simple_class(mock_class):
mock_class.return_value.explode.return_value = "BOO!"
inst = simple.SimpleClass()
result = inst.explode()
print(result)
A more appropriate way to solve this is to use patch.object
@patch.object(MyClass, "do_something")
def test_mock_my_class(m):
m.side_effect = ['Mocked Output']
my_class = MyClass()
assert my_class.do_something() == 'Mocked Output'
Personally, patch.object
confuses me. After reading this article , I have decided to stick with patch
only.
The problem with the patch in the question is that the MyClass
patched is not the MyClass
used in the test function. Refer to this guide for a more in-depth explanation of where patch should be applied.
The path of the patch should be tst.test_my_class.MyClass
, as shown in the code below.
from unittest.mock import patch
import unittest
from src.module.my_class import MyClass
class Test(unittest.TestCase):
def test_my_class(self):
my_class = MyClass()
self.assertTrue(my_class.do_something() == 'Real Output')
@patch('test.test_my_class.MyClass')
def test_mock_my_class(self, mock_my_class):
mock_my_class.return_value.do_something.return_value = 'Mocked Output'
my_class = MyClass()
self.assertTrue(my_class.do_something() == 'Mocked Output')
Run this command to execute it in a terminal.
python3 -m unittest discover
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.