piggs_boson
piggs_boson

Reputation: 1007

Mock patch with __init__.py

My code is organized as follows:

dir/A.py:

from X import Y

class A:
    ...

dir/__init__.py:

from .A import A
__all__ = ['A']

tests/test_A.py:

class test_A:
    @patch("dir.A.Y")
    def test(self, mock_Y):
        ....

On running tests/test_A.py, I (as expected) get the error:

AttributeError: <class 'dir.A.A'> does not have the attribute 'Y'

The issue is that @patch("dir.A.y") tries to find Y in class dir.A.A, rather than in the module dir.A (where it is actually present).

This is clearly because of my __init__.py. I could overcome this by changing the module-name A and the class-name A to different symbols.

The way the code is organized, I want to avoid such a naming change. How can I use patch in a way that it finds Y in the correct place?

Upvotes: 11

Views: 5567

Answers (1)

Sven Marnach
Sven Marnach

Reputation: 601679

You can use the patch.object() decorator instead, and retrieve the module from sys.modules:

@patch.object(sys.modules['dir.A'], 'Y')
def test(self, mock_Y):
    ...

Upvotes: 17

Related Questions