我想在isinstance(obj,requests.Response)逻辑中编写一些测试用例来运行object_check.在我创建Mock数据作为requests.post的返回值之后.模拟数据的类型始终是Mock类.这样,我怎样才能重写模拟数据,因此模拟数据可以是request.Response?所以我可以锻炼线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)
解决方法:
你可以这样做:
@patch.object(requests, 'post')
def test_service_post(mock_request_post):
data = {'number': 0000, 'user_id': 0, 'name': 'john'}
def res():
r = requests.Response()
r.status_code = 200
def json_func():
return data
r.json = json_func
return r
mock_request_post.return_value = res()
assert data == service_post(data)
当我在本地运行时,测试然后通过了我.请注意,模拟是一种迷你气味.
我曾经是Mock的忠实粉丝.然而,当我成长为开发者时,我真的试图避免它.它可以诱骗你进入一些非常糟糕的设计,并且它们可能真的很难维护(特别是因为你正在修改你的Mock以保持返回值).模拟还可以创建一种虚假的安全感(即使Web服务发生显着变化,您的测试也会继续通过,因此您可能会在prod中爆炸).我认为你真的不需要它.两种选择:
>你可以点击你想要击中的任何服务,并用pickle序列化(保存)该响应,并存储到磁盘(保存在你的测试套件中).然后让你的单元测试读回来并使用实际的响应对象.您仍然需要修改requests.post,但至少会为您排列返回值,您不必在需求/应用程序增长时添加或修改它们.
>刚上网.完全忘记补丁:只需在测试中执行POST并检查响应.当然,这可能很慢,只有在你有互联网的情况下才有效.你会得到愚蠢的纯粹主义者,他们会告诉你永远不要在单元测试中这样做.如果遇到其中一个纯粹的人,可能会将其移至集成测试.但是说真的,没有什么可以替代你在生产中做的事情.这样做的好处是,如果Web服务发生变化,那么您将立即了解它并修复您的代码.缺点是它可能会降低您的测试套件速度,这可能是一个不可靠的测试(如果Web服务失败,您的测试将失败……但实际上可能知道这一点很好).
我建议如果网络服务不稳定(即易于更改),请使用选项2.否则,使用选项1.或者两者兼而有之(模拟和补丁用于单元测试,并在集成测试中点击服务).只有你可以决定!
HTH,祝你好运!