如何在函数 python 测试中模拟函数?

How to mock a function inside a function python test?

我有这些文件:

utils.py

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

generate.py

from utils import generateCode

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

test.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')

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

answer!='123456'

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

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

解决方案 1

相反,在 generate.py 中模拟 generateCode 的本地版本。所以在你的 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