I want to write a unit test to a function which instantiates twice a dataclass followed by calling its method. However, the actual calls of the instantiation includes the calling of the method. This is confusing to me.
Here is my code.
person.py
<code>from dataclasses import dataclass
@dataclass
class Person:
name: str
def work(self):
print(f"{self.name} is working")
def run_person():
# It instantiates Person twice.
for n in ["John", "Jack"]:
person = Person(name=n) # Instantiate a person
person.work() # Calling its method .work()
</code>
<code>from dataclasses import dataclass
@dataclass
class Person:
name: str
def work(self):
print(f"{self.name} is working")
def run_person():
# It instantiates Person twice.
for n in ["John", "Jack"]:
person = Person(name=n) # Instantiate a person
person.work() # Calling its method .work()
</code>
from dataclasses import dataclass
@dataclass
class Person:
name: str
def work(self):
print(f"{self.name} is working")
def run_person():
# It instantiates Person twice.
for n in ["John", "Jack"]:
person = Person(name=n) # Instantiate a person
person.work() # Calling its method .work()
test_person.py
<code>import unittest
from unittest.mock import MagicMock, call, patch
from person import run_person
class TestMain(unittest.TestCase):
@patch("person.Person") # Patch the Person dataclass
def test_run_person(self, mock_person):
mock_person.return_value = MagicMock()
# This is my expectation. It should call Person() twice.
# But the actual calls is
# [call(name='John'), call().work(), call(name='Jack'), call().work()]
expected_calls = [call(name="John"), call(name="Jack")]
run_person()
mock_person.assert_has_calls(expected_calls)
if __name__ == "__main__":
unittest.main()
</code>
<code>import unittest
from unittest.mock import MagicMock, call, patch
from person import run_person
class TestMain(unittest.TestCase):
@patch("person.Person") # Patch the Person dataclass
def test_run_person(self, mock_person):
mock_person.return_value = MagicMock()
# This is my expectation. It should call Person() twice.
# But the actual calls is
# [call(name='John'), call().work(), call(name='Jack'), call().work()]
expected_calls = [call(name="John"), call(name="Jack")]
run_person()
mock_person.assert_has_calls(expected_calls)
if __name__ == "__main__":
unittest.main()
</code>
import unittest
from unittest.mock import MagicMock, call, patch
from person import run_person
class TestMain(unittest.TestCase):
@patch("person.Person") # Patch the Person dataclass
def test_run_person(self, mock_person):
mock_person.return_value = MagicMock()
# This is my expectation. It should call Person() twice.
# But the actual calls is
# [call(name='John'), call().work(), call(name='Jack'), call().work()]
expected_calls = [call(name="John"), call(name="Jack")]
run_person()
mock_person.assert_has_calls(expected_calls)
if __name__ == "__main__":
unittest.main()
The test gives an error
<code>Expected: [call(name='John'), call(name='Jack')]
Actual: [call(name='John'), call().work(), call(name='Jack'), call().work()]
</code>
<code>Expected: [call(name='John'), call(name='Jack')]
Actual: [call(name='John'), call().work(), call(name='Jack'), call().work()]
</code>
Expected: [call(name='John'), call(name='Jack')]
Actual: [call(name='John'), call().work(), call(name='Jack'), call().work()]
Can you please explain why I receive the error message above. Shouldn’t the call of Person()
and the call of Person.work()
be separated? And can you please show me how to write this test properly?
Thanks