【问题标题】:python3 unit testing, patching return of instance method not workingpython3单元测试,修补实例方法的返回不起作用
【发布时间】:2020-03-09 03:20:07
【问题描述】:

我正在尝试执行以下操作:

@patch('uuid.uuid4', autospec=True)
def test_generate_adid(self, patched_uuid, app_api):
    patched_uuid.return_value = "9e51ab81-6d65-4b81-af3b-8f7f49d69ba7"
    adid = app_api.generate_adid()
    assert adid == "9e51ab81-6d65-4b81-af3b-8f7f49d69ba7"

其中app_api 是被测类的一个fixture。

但是,在我的 app_api 类中,uuid4() 没有得到修补,并且不断返回一个 uuid,而不是我试图强制使用的 uuid。 generate_adid() 实例方法如下所示:

from uuid import uuid4    
def generate_adid(self):
        adid = str(uuid4())
        return adid

失败的单元测试错误:

AssertionError: assert '90b29e86-e3b0-40aa-8971-f868f90cb009' == '9e51ab81-6d65-4b81-af3b-8f7f49d69ba7'

我已经查阅了这个帖子:How to mock uuid generation in a test case?,但仍然没有运气。

我做错了什么?感谢所有提前回复的人。

编辑:这是完整的代码:

from requests import Session
from random import uniform
from hashlib import md5
from hmac import new
from uuid import uuid4
from json import dumps

class AppApi:

    def __init__(self, account):
        self.account = account
        self.session = Session()

    def generate_adid(self):
        adid = str(uuid4())
        return adid

测试用例:

from src import AppApi
from pytest import fixture
from unittest.mock import patch
from json import loads


ACCOUNT = {
    "email": "user@email.com",
    "username": "user",
    "password": "s3cr3t"
}

@fixture
def app_api():
    app_api = AppApi(ACCOUNT)
    yield app_api

class TestAppApi:

    @patch('uuid.uuid4')
    def test_generate_adid(self, patched_uuid, app_api):
        patched_uuid.return_value = "9e51ab81-6d65-4b81-af3b-8f7f49d69ba7"
        adid = app_api.generate_adid()
        assert adid == "9e51ab81-6d65-4b81-af3b-8f7f49d69ba7"

【问题讨论】:

    标签: python-3.x unit-testing pytest uuid


    【解决方案1】:

    在您的示例中,您正在修补 uuid 模块中的 uuid4() 函数,而不是您尝试测试的模块中的函数 uuid4()。看看Python unnit.test docs where to patch

    使用上面的示例,您需要修补导入到 src 模块中的 uuid4()。你需要使用@patch("src.uuid4")

    from src import AppApi
    from pytest import fixture
    from unittest.mock import patch
    from json import loads
    
    
    ACCOUNT = {
        "email": "user@email.com",
        "username": "user",
        "password": "s3cr3t"
    }
    
    @fixture
    def app_api():
        app_api = AppApi(ACCOUNT)
        yield app_api
    
    class TestAppApi:
    
        @patch('src.uuid4')
        def test_generate_adid(self, patched_uuid, app_api):
            patched_uuid.return_value = "9e51ab81-6d65-4b81-af3b-8f7f49d69ba7"
            adid = app_api.generate_adid()
            assert adid == "9e51ab81-6d65-4b81-af3b-8f7f49d69ba7"
    

    希望这会有所帮助!

    【讨论】:

    • 我正在尝试修补uuid 模块中的uuid4()。话虽如此,这仍然不能解决我的问题。
    • 您必须修补导入到应用程序代码中的函数。您能否扩展您的示例,我可以尝试提供帮助
    • 我已经用完整的代码编辑了原始帖子。请注意我在__init__.py 中导入了AppApi,这就是为什么我可以直接从我的src 目录中导入它。
    • 谢谢,这成功了!不过要注意,我必须在 @patch 装饰器中指定整个路径。因此,为了通过测试,我需要执行以下操作:@patch('src.app_api.uuid4')
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多