I've been trying for days to mock the instance of a certain class. I've tried dozens of approaches... I'm starting to think that this is not possible.
The code below is the only one, so far, that I've tested that can patch the SomeClassToMock class (note that I need to use __new__
to work). However the error TypeError: object.__new__() takes exactly one argument (the type to instantiate)
occurs when "test_some_method_b" is called... If I just run "test_some_method_b" or "test_some_method_a", the error doesn't occur (weird? )!
I don't know if there's something wrong, but I really need to instantiate (mock) SomeClassToMock in a controlled way.
Is there any possible solution?
CODE
import unittest
from unittest import mock
from some.path import SomeClassToMock
from path.to.module_to_test import ClassToTest
class SomeClassTest(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_some_method_a(self):
mocked_op = SomeClassToMock(**{
"some_key_a": 770675,
"some_key_b": "BLAHBLAHBLAHBLAH",
"some_key_c": 2740,
"some_key_d": 343.4,
"some_key_e": "09/06/2022",
"some_key_f": "1170720100038737"
})
patcher = mock.patch("some.path.SomeClassToMock.__new__", return_value=mocked_op)
patcher.start()
effective_op = ClassToTest().method_to_test(
"value_a",
"value_b",
"value_c",
"value_d"
)
patcher.stop()
self.assertEqual(mocked_op, effective_op)
def test_some_method_b(self):
mocked_op = SomeClassToMock(**{
"some_key_a": 770675,
"some_key_b": "BLAHBLAHBLAHBLAH",
"some_key_c": 2740,
"some_key_d": 343.4,
"some_key_e": "09/06/2022",
"some_key_f": ""
})
patcher = mock.patch("some.path.SomeClassToMock.__new__", return_value=mocked_op)
patcher.start()
effective_op = ClassToTest().method_to_test(
"value_a",
"value_b",
"value_c",
"value_d"
)
patcher.stop()
self.assertEqual(mocked_op, effective_op)
PYTEST OUTPUT
(project_name) [username@username-pc project_name]$ pytest -v /home/username/tests/certain/path/file_test.py
================================================================= test session starts =================================================================
platform linux -- Python 3.8.12, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- /home/username/.pyenv/versions/3.8.12/envs/project_name/bin/python3.8
cachedir: .pytest_cache
rootdir: /home/username/tests
plugins: forked-1.1.3, xdist-1.32.0, cov-2.8.1
collected 2 items
certain/path/file_test.py::SomeClassTest::test_some_method_a PASSED [ 50%]
certain/path/file_test.py::SomeClassTest::test_some_method_b FAILED [100%]
====================================================================== FAILURES =======================================================================
___________________________________________________ SomeClassTest.test_some_method_b ___________________________________________________
self = <certain.path.file_test.SomeClassTest testMethod=test_some_method_b>
def test_some_method_b(self):
> mocked_op = SomeClassToMock(**{
"some_key_a": 770675,
"some_key_b": "BLAHBLAHBLAHBLAH",
"some_key_c": 2740,
"some_key_d": 343.4,
"some_key_e": "09/06/2022",
"some_key_f": ""
})
E TypeError: object.__new__() takes exactly one argument (the type to instantiate)
certain/path/file_test.py:37: TypeError
=============================================================== short test summary info ===============================================================
FAILED certain/path/file_test.py::SomeClassTest::test_some_method_b - TypeError: object.__...
============================================================= 1 failed, 1 passed in 1.57s =============================================================
Thanks!