You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何断言被Patch的request.get()调用传入的URL参数?

如何断言被Patch的request.get()的输入参数

我来给你捋捋怎么解决这个问题哈~你现在的问题是用@mock.patch('request.get', new=mock_response_200)这种方式替换原函数后,测试函数里拿不到mock的调用记录,没法断言传入的URL。这里有两种常用的解决方案:

方法一:利用mock的side_effect和注入的mock对象(推荐)

这种方法既保留了你自定义的mock响应逻辑,又能借助mock库自带的调用记录功能来做断言,是更规范的做法:

首先修改你的测试脚本,去掉new参数,改用side_effect,同时让测试函数接收patch生成的mock对象作为参数:

def mock_response_200(url): 
    response = mock.MagicMock() 
    response.status_code = 200 
    response.json = mock.Mock(return_value={ 0: {'key1': 'value1', 'key2': 'value2'} }) 
    return response 

@mock.patch('request.get')  # 这里不再指定new参数
def test_get_data(mock_get): 
    # 让mock对象的side_effect指向我们的自定义响应函数
    mock_get.side_effect = mock_response_200
    
    arg1 = 'arg1' 
    arg2 = None 
    arg3 = 'arg3' 
    stuff = get_data(arg1, arg2, arg3) 
    
    # 断言request.get被调用时传入的URL是否符合预期
    mock_get.assert_called_once_with('some_url?arg1&arg3')

原理说明:

当你用@mock.patch('request.get')而不指定new时,mock库会自动创建一个Mock实例来替代原函数,并把这个实例注入到测试函数的参数(这里是mock_get)中。我们给这个mock对象的side_effect赋值为你的mock_response_200函数,这样每次调用request.get()时,都会执行mock_response_200并返回你定义的响应,同时mock_get会自动记录所有的调用参数,你就可以用assert_called_once_with()来验证传入的URL是否正确了。

方法二:在自定义mock函数中记录调用参数

如果你不想修改patch的方式,也可以在mock_response_200里添加一个变量来记录每次调用的URL:

def mock_response_200(url): 
    # 给函数添加一个属性来存储调用过的URL(用列表是因为它是可变对象,能在外部访问)
    if not hasattr(mock_response_200, 'called_urls'):
        mock_response_200.called_urls = []
    mock_response_200.called_urls.append(url)
    
    response = mock.MagicMock() 
    response.status_code = 200 
    response.json = mock.Mock(return_value={ 0: {'key1': 'value1', 'key2': 'value2'} }) 
    return response 

@mock.patch('request.get', new=mock_response_200) 
def test_get_data(): 
    arg1 = 'arg1' 
    arg2 = None 
    arg3 = 'arg3' 
    
    # 先清空记录,避免其他测试用例的影响
    mock_response_200.called_urls.clear()
    
    stuff = get_data(arg1, arg2, arg3) 
    
    # 断言调用的URL是否正确
    assert mock_response_200.called_urls == ['some_url?arg1&arg3']

这种方法的思路是利用函数作为对象的特性,给它动态添加一个属性来存储调用记录,之后在测试函数里直接检查这个属性即可。不过相比第一种方法,它需要自己维护调用记录的状态,容易受其他测试用例的影响,所以更推荐第一种方案。

内容的提问来源于stack exchange,提问作者Koen

火山引擎 最新活动