2

I want to test a module A which uses decorators with arguments. The arguments get evaluated when the module A is loaded. For some of the decorator args, I set the value by calling a function foo in module B.

# A.py
import B

@deco(arg1=B.foo())
def bar():
  ...

When I want to test A, I want to mock B.foo so that the decorator argument is set for my test cases. I think that B.foo must be mocked before A loads B.

In the unit test, as a caller of A, how do I mock B.foo to ensure the mocked version is used when evaluating the decorator arguments in A?

CppNoob
  • 2,322
  • 1
  • 24
  • 35

1 Answers1

2

If you want to ensure that the mock is really used, you have to reload module A after patching foo, as bar already had been evaluated with the original foo. You could wrap that in a fixture like this (untested):

import importlib
import pytest
from unittest import mock
import A

@pytest.fixture
def mocked_foo():
    with mock.patch('B.foo') as mocked:
        importlib.reload(A)
        yield mocked

def test_bar(mocked_foo):
    ...
MrBean Bremen
  • 14,916
  • 3
  • 26
  • 46