Python 在使用pytest时模拟装饰器中的对象

Python 在使用pytest时模拟装饰器中的对象,python,python-3.x,pytest,python-unittest,python-decorators,Python,Python 3.x,Pytest,Python Unittest,Python Decorators,在下面的例子中,我有一个装饰师。在decorator中,我正在实例化一个DB连接类。下面有一个测试类,我想在装饰器中模拟DB连接类。我该怎么做 # importing libraries import time import math # decorator to calculate duration # taken by any function. def calculate_time(func): # added arguments inside the inner1

在下面的例子中,我有一个装饰师。在decorator中,我正在实例化一个DB连接类。下面有一个测试类,我想在装饰器中模拟DB连接类。我该怎么做

# importing libraries 
import time 
import math 

# decorator to calculate duration 
# taken by any function. 
def calculate_time(func): 

    # added arguments inside the inner1, 
    # if function takes any arguments, 
    # can be added like this. 
    def inner1(*args, **kwargs): 

        db_conn = DBConn()
        # storing time before function execution 
        begin = time.time() 

        func(*args, **kwargs) 

        # storing time after function execution 
        end = time.time() 
        db_conn.logTime(begin, end)
        print("Total time taken in : ", func.__name__, end - begin) 

    return inner1 



# this can be added to any function present, 
# in this case to calculate a factorial 
@calculate_time
def test_factorial(num): 

    # sleep 2 seconds because it takes very less time 
    # so that you can see the actual difference 
    time.sleep(2) 
    print(math.factorial(num)) 

# calling the function. 
factorial(10) 

好的,让这更清楚:
假设您的模块位于包
mypackage
中,并且您的模块
calculate\u time.py
与decorator类似:

from mypackage.dbconn import DBConn

def calculate_time(func):
    def inner1(*args, **kwargs):
        ...
模块
factorial.py
包含:

from mypackage.calculate_time import calculate_time

@calculate_time
def factorial(num):
    time.sleep(2)
    print(math.factorial(num))
然后,您的测试可以如下所示:

from unittest.mock import patch    
from mypackage.factorial import factorial

class FakeConn:
    def logTime(self, begin, end):
        print(begin, end)

@patch('mypackage.calculate_time.DBConn', new=FakeConn)
def test_factorial():
    print(factorial(10))

好的,让这更清楚:
假设您的模块位于包
mypackage
中,并且您的模块
calculate\u time.py
与decorator类似:

from mypackage.dbconn import DBConn

def calculate_time(func):
    def inner1(*args, **kwargs):
        ...
模块
factorial.py
包含:

from mypackage.calculate_time import calculate_time

@calculate_time
def factorial(num):
    time.sleep(2)
    print(math.factorial(num))
然后,您的测试可以如下所示:

from unittest.mock import patch    
from mypackage.factorial import factorial

class FakeConn:
    def logTime(self, begin, end):
        print(begin, end)

@patch('mypackage.calculate_time.DBConn', new=FakeConn)
def test_factorial():
    print(factorial(10))

db\u conn=new DBConn()
。这看起来像是语法错误<代码>DBConn()也未定义。如何实例化对象对于如何模拟对象很重要。@jordanm抱歉,这是一个输入错误。DBConn()是我在这里添加的示例,以了解如何模拟它。这取决于它的定义/imported@jordanm该函数按预期工作。但是,我想创建一个模拟类,而不是创建一个实际的类。通常我使用decorator补丁(packagename.DBConn)来修补它。但是,由于它是一个decorator,我不确定如何将补丁decorator与计算时间decorators结合起来。如果它像从xxx import DBConn导入的那样导入,那么就应该像导入一样模拟它,例如
@patch('.DBConn')
。因为装修工的缘故,这里没什么特别的。如果您将如何导入
DBConn
添加到问题中,将会有所帮助。
db\u conn=new DBConn()
。这看起来像是语法错误<代码>DBConn()也未定义。如何实例化对象对于如何模拟对象很重要。@jordanm抱歉,这是一个输入错误。DBConn()是我在这里添加的示例,以了解如何模拟它。这取决于它的定义/imported@jordanm该函数按预期工作。但是,我想创建一个模拟类,而不是创建一个实际的类。通常我使用decorator补丁(packagename.DBConn)来修补它。但是,由于它是一个decorator,我不确定如何将补丁decorator与计算时间decorators结合起来。如果它像从xxx import DBConn导入的那样导入,那么就应该像导入一样模拟它,例如
@patch('.DBConn')
。因为装修工的缘故,这里没什么特别的。如果您将如何导入
DBConn
添加到您的问题中,将会有所帮助。