Reputation: 541
My goal is to test a class without calling its initializer (because the initializer has some side effects I want to prevent from happening for that test).
I can achieve this with the code in test_1
, which works fine by itself. However it seems to somehow contaminate the init/new methods, because test_2
fails when run right after test_1
with:
TypeError: object.__new__() takes exactly one argument (the type to instantiate)
When running each test individually, they both pass.
Any idea what is happening here and how I can fix this, i.e., how to properly reset the init/new methods after mocking and testing?
import pytest
# The class to test:
class A:
def __init__(self, x):
self.x = x
def test_1(mocker):
"""First test uses the class without triggering the initializer."""
# Create object without triggering the initializer:
a = A.__new__(A)
# Store away the old methods:
new_orig = A.__new__
init_orig = A.__init__
# Mock new/init methods:
mocker.patch.object(A, "__new__", return_value=a)
mocker.patch.object(A, "__init__", return_value=None)
# Do the test:
res = A()
# ...
# Restore new/init methods:
A.__init__ = init_orig
A.__new__ = new_orig
def test_2():
"""Second test uses the class as intended."""
A(2)
Upvotes: 0
Views: 1491
Reputation: 1045
If you only want to avoid calling __init__
, you can do it with the following code, without patching in __new__
.
import pytest
# The class to test:
class A:
def __init__(self, x):
self.x = x
def test_1(mocker):
"""First test uses the class without triggering the initializer."""
mocker.patch.object(A, "__init__", return_value=None)
# Do the test:
res = A()
with pytest.raises(AttributeError):
print(res.x)
# ...
def test_2():
"""Second test uses the class as intended."""
a = A(2)
assert(a.x == 2)
No need to store the new/init methods either.
Upvotes: 4