I have following project structure:
├───pa
│ |───__init__.py
| |─── a1.py
| |─── test_a1.py
|
├───pb
│ |───__init__.py
| |─── b1.py
With following code: b1.py:
class B1:
def __init__(self):
self.text = "Unmocked_B1"
def get_text(self):
return self.text
pb.__init__.py:
from .b1 import B1
a1.py:
from src.pb import B1
class A1:
def __init__(self):
self.b = B1()
def get_text(self):
return self.b.get_text()
pa.__init__.py:
from .a1 import A1
And I want to mock self.b in class A1 using unittest.mock.patch in such way that following code in test_a1.py will print "Mocked B1"
test_a1.py:
from unittest import TestCase
from unittest.mock import patch, PropertyMock
from . import A1
class TestB1(TestCase):
@patch('Some args')
def test_get_text(self, mocked_b1):
# Some code
a1 = A1()
print(a1.get_text()) # Should print: Mocked B1
I tried both mocking B1 import with:
@patch('src.pb.b1.B1')
def test_get_text(self, mocked_b1):
mocked_b1.get_text.return_value = 'Mocked B1'
a1 = A1()
print(a1.get_text()) # Should print: Mocked B1
And mocking property of a1 with property mock:
@patch('pa.a1.A1.b', new_callable=PropertyMock)
def test_get_text(self, mocked_b):
mocked_b.get_text.return_value = 'Mocked B1'
a1 = A1()
print(a1.get_text()) # Should print: Mocked B1
Which does not seem to work even when I make attribute b inside A1 static instead of dynamic.
Is there a way to mock this attribute? It would be perfect if it would work on dynamic attribute as shown earlier.
I'm using python 3.10
Try the following syntax that uses patch.object
and context manager (instruction with
):
class TestB1(TestCase):
def test_get_text(self):
a1 = A1()
with patch.object(a1, "b") as mocked_b1:
mocked_b1.get_text.return_value = 'Mocked B1'
print(a1.get_text()) # Prints: Mocked B1