Bypassing a decorator for unit testing [duplicate]

女生的网名这么多〃 提交于 2021-02-20 03:51:51

问题


I have a decorator @auth which basically checks a database to ensure a user can access a given REST call. I would like to write some unit tests for these calls. My initial idea was to simply monkeypatch the decorator into a pass through that does nothing. (My initial idea failed, so I may just monkeypatch some function inside of @auth so that it always passes, but I'm still curious if I can bypass a decorator completely)

I threw together a quick sample of what I was hoping to accomplish.

example.py

# example.py
from __future__ import print_function

def sample_decorator(func):
    def decorated(*args, **kwargs):
        print("Start Calculation")
        ans = func(*args, **kwargs) + 3
        print(ans)
        print("Finished")
        return ans
    return decorated

@sample_decorator
def add(a, b):
    return a + b

test_example.py

# test_example.py
from __future__ import print_function
import pytest

import example

def test_add_with_decorator():
    assert example.add(1, 1) == 5

def testadd_with_monkeypatch_out_decorator(monkeypatch):
    monkeypatch.setattr(example, 'sample_decorator', lambda func: func)
    assert example.add(1, 1) == 2  # this fails, but is the behaviour I want

Is there some straight forward way to accomplish this?


回答1:


The decorator can set an attribute on the wrapping function to give access to the wrapped function.

Something along the line of

def wrap_foo(func):
 def decorated(*args, **kwargs):
  func(*args, **kwargs)
 decorated.__wrapped__ = func
 return decorated

@wrap_foo
def foo():
 pass

# Wrapped
foo()

# Unwrapped
foo.__wrapped__()



回答2:


Just keep the definitions separate:

def raw_add...

add = sample_decorator(raw_add)

assert example.raw_add...


来源:https://stackoverflow.com/questions/41206565/bypassing-a-decorator-for-unit-testing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!