首页 > 解决方案 > 如何在函数 python 测试中模拟函数?

问题描述

我有这些文件:

实用程序.py

def generateCode():
    while(True):
        # https://tools.ietf.org/html/rfc4122.html
        uuid_code = str(uuid.uuid4().int)[:6]
        return uuid_code

生成.py

from utils import generateCode

def create_auth_challenge():
   code = generateCode()
   return code

测试.py

from unittest.mock import patch
from generate import create_auth_challenge

@patch('utils.generateCode', return_value='123456')
def test_create_auth_challenge(self, mock_generateCode):
   answer = create_auth_challenge()
   self.assertEqual(answer,'123456')

但问题是测试结果失败是因为

答案!='123456'

所以,我认为这是因为模拟过程是错误的,因为答案值总是一个随机数。是什么让它错了?是因为uuid4吗?如何进行正确的嘲笑?

标签: pythonunit-testingmocking

解决方案


在你打补丁之前utils.generateCode,文件generate.py已经导入了原始文件utils.generateCode并在本地分配为generateCode,因此更新的补丁不会反映。

解决方案 1

相反,模拟generate.pygenerateCode的本地版本。所以在你的test.py中改变它:

@patch('utils.generateCode', return_value='123456')

至:

@patch('generate.generateCode', return_value='123456')

解决方案 2

如果您希望保留对源的补丁,则只有在补丁生效后才utils.generateCode导入文件generate.py 。因此,将您的test.py更改为:

...
# from generate import create_auth_challenge  # Remove this import
...
@patch('utils.generateCode', return_value='123456')
def test_create_auth_challenge(mock_generateCode):
    from generate import create_auth_challenge  # Move the import here
    ...
...

解决方案 3

您还可以更改generate.py以从源代码中使用它utils。因此,将您的generate.py更改为:

import utils

def create_auth_challenge():
   code = utils.generateCode()
   return code

推荐阅读