So I have the following example code:
import pytest
class Helper:
def function1(self):
print("helper function called")
class SUT:
def real_function(self):
helper = Helper()
helper.function1()
print("real function called")
def test_Test(monkeypatch):
test = SUT()
def stub_function1(self):
print("helper is stubbed")
monkeypatch.setattr(Helper, "function1", stub_function1)
test.real_function()
and running pytest .\test_scratch_1.py --capture=tee-sys
prints out helper is stubbed
and real function called
, as expected.
However, I would actually like to be able print out helper function called
before helper is stubbed
, thus not fully stubbing the function but rather sort of decorate the function with things to do after it runs. I tried the following:
import pytest
class Helper:
def function1(self):
print("helper function called")
class SUT:
def real_function(self):
print("real function called")
def test_Test(monkeypatch):
test = SUT()
helper_original = Helper()
def stub_function1(helper_original_not_stubbed):
helper_original_not_stubbed.function1()
print("helper is stubbed")
monkeypatch.setattr(Helper, "function1", stub_function1(helper_original))
test.real_function()
But this produces the same result. Does anyone know how to achieve this?
CodePudding user response:
You can wrap a decorator around your method prior to calling it.
def my_decorator(function):
def wrapped_func(*args, **kwargs):
print("before")
rt = function(*args, **kwargs)
print("after")
return rt
return wrapped_func
def test_Test():
test = SUT()
test.function1 = my_decorator(test.function1)
test.function1()
CodePudding user response:
So you are actually doing an infinite recursive call with your current solution.
Monkeypatch is to mock a dependency that can be tough to test. So you are misusing it in the above example.
If you wan't something printed before and after then do:
import pytest
class SUT:
def function1(self):
print("abc")
def test_Test(monkeypatch):
test = SUT()
print("before")
test.function1()
print("after")