myke
myke

Reputation: 541

Testing a class without calling its initializer

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

Answers (1)

OctaveL
OctaveL

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

Related Questions