dimanche 8 novembre 2020

How to patch the __new__ method of a class

My goal is to patch a class' __new__ method in order to control the exact object it creates in a test case. See the code below.

Each of the two tests test_1 and test_2 work as expected when run individually. When they are both run consecutively, however, test_2 fails with:

TypeError: object.__new__() takes exactly one argument (the type to instantiate)

Even if I store away the original __new__ method pointer and restore it at the end of test_1 (something that pytest takes care of anyway) it still produces the same result.

Any idea what is going on here? And what a working approach could be to achieve my goal?

import pytest


# The class:
class A:
    def __init__(self, x):
        self.x = x


def test_1(mocker):
    """First test patches the new method."""
    # Create object:
    a = A(x=3)
    # Make sure new method always returns this object:
    mocker.patch.object(A, "__new__", return_value=a)
    # Switch off the initializer (so it doesn't overwrite values in the pre-made object):
    mocker.patch.object(A, "__init__", return_value=None)
    # Do the test:
    res = A(x=1)
    assert res.x == 3


def test_2():
    """Second test uses the class as intended."""
    A(2)  # <- Fails (when run right after test_1)

Aucun commentaire:

Enregistrer un commentaire