我想写一些测试用例来练习isinstance(obj)中的object_check,请求。响应)逻辑。在我创建模拟数据作为请求.post. 模拟数据的类型始终是模拟类。这样,我如何重写模拟数据以便模拟数据可以是请求。回应?所以我可以练习d = obj.json()
?在
from unittest.mock import patch, Mock
import unittest
import requests
from requests.exceptions import HTTPError
import pytest
def object_check(obj):
if isinstance(obj, bytes):
d = ujson.decode(obj.decode())
elif isinstance(obj, requests.Response):
d = obj.json()
else:
raise ValueError('invalid type')
return d
def service_post(params):
"""
trivial function that does a GET request
against google, checks the status of the
result and returns the raw content
"""
url = "https://www.iamdomain.com"
params = {'number': 1234, 'user_id': 1, 'name': 'john'}
resp = requests.post(url, data=params)
return object_check(resp)
@patch.object(requests, 'post')
def test_service_post(mock_request_post):
data = {'number': 0000, 'user_id': 0, 'name': 'john'}
def res():
r = Mock()
r.status_code.return_value = 200
r.json.return_value = data
return r
mock_request_post.return_value = res()
assert data == service_post(data)
你可以这样做:
当我在本地运行这个测试时,它通过了。注意Mock是一种很小的气味。
我以前是
Mock
的超级粉丝。不过,随着我成长为一个开发人员,我真的努力避免它。它可以欺骗您进入一些非常糟糕的设计,并且它们很难维护(特别是因为您正在修改Mock
来保存返回值)。^{prod1>你的服务可能会继续进行安全性测试(如果你的cd1的安全性测试通过的话)。我不认为你真的需要它。两种选择:pickle
序列化(保存)这个响应,然后存储到磁盘(保存在你的测试套件中)。然后让您的单元测试读回它并使用实际的响应对象。您仍然需要patch
而不是requests.post
,但至少返回值将为您排队,并且您不必随着需求/应用程序的增长而添加或修改它们。在patch
:只需在测试中发布文章并检查响应。当然,这可能很慢,而且只有在你有互联网的情况下才有效。你会得到愚蠢的纯粹主义者,他们会告诉你不要在单元测试中这样做。如果你遇到一个纯粹的人,也许可以把它转移到一个集成测试中。但是说真的,在prod中做你真正要做的事情是没有替代品的,这样做的好处是,如果web服务发生了变化,那么你马上就会知道它并可以修改你的代码。缺点是它会减慢您的测试套件,而且它是一个潜在的不可靠的测试(如果web服务停止运行,您的测试将失败…但事实上知道这一点可能是很好的)。在我建议如果Web服务不稳定(即容易更改),请使用选项2。否则,使用选项1。或者组合使用(
Mock
和patch
进行单元测试,并在集成测试中命中服务)。只有你能决定!在祝你好运!在
如果要模拟
text
或content
@属性值,请在text
周围使用PropertyMock
实例化mock时使用^{} 参数:
另请注意,
^{pr2}$r.status_code.return_value = 200
不能与speccing一起使用;请直接设置该值:相关问题 更多 >
编程相关推荐