如何在Python单元测试中模拟外部服务器?
我有几个单元测试需要很长时间(几分钟),因为它们要调用一些外部服务(比如Twitter、Facebook、Klout等)。
我想把这些服务的结果缓存起来,这样就可以直接使用这些结果,而不需要太多改动我的现有测试。缓存的关键取决于网址、查询参数、请求头等等,所以这个过程有点复杂。
请问有什么好的方法可以做到这一点?
3 个回答
2
从技术上讲,如果你的测试使用了外部服务,那就不是单元测试,而是集成测试。为了进行单元测试并加快你的测试代码,可以使用模拟对象。关于Python的模拟对象,你可以在这里找到详细信息:
http://python-mock.sourceforge.net/
3
这是代码,我们使用requests库来调用外部的API。所以我们创建了一个上下文处理器,并用一个模拟的请求对象。
如果我们要测试get_data这个函数,下面就是我们如何模拟请求外部API的方式:
import requests
import mock
import unittest
def get_data(url):
resp = requests.get(url)
return resp
class GetDataTest(unittest.TestCase):
def test_get_data(self):
with mock.patch.object(requests, 'get') as get_mock:
get_mock.return_value = mock_response = mock.Mock()
mock_response.status_code = 200
mock_response.content = {'twitter_handle': '@twitter'}
resp = get_data("http://this_address_does_not_exist.com")
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.content['twitter_handle'], '@twitter')
9
你通常会使用某种适配器来连接这些外部服务或模块。这些适配器就像是你和外部世界的接口,可以根据不同的情况模拟(mock)和生成假响应。
我尝试过很多模拟库,最后发现Mock是最适合我的一个。