您可以在这里使用两种方法:
- 使用伪造的 twilio 客户端并用于对代码进行单元测试
- 使用真实客户和测试账户
对于单元测试,方法 1 通常是一个更好的主意,因此,例如,您可以离线运行测试并且测试执行得更快。您还需要测试您的代码,但使用方法 2,您还将测试 twilio 本身。
这带来了另一个问题:我们如何确保您的假客户端与真实客户端足够接近,以使您的测试有用?
在最好的情况下,twilio 会发布并维护这样的测试客户端,但看起来他们没有。
您可以做的是结合这些方法:拥有假客户端(方法 1)并进行一些测试以验证您的假客户端与真实客户端的行为相同。
但是您可以从方法 1 开始 - 您需要构建您的测试客户端(通常是非常简单的东西)并确保它与真实客户端足够接近(也许切换到真实客户端并确保你的测试仍然有效)。
这里的危险是,如果在 twilio 方面有一些破坏性的 API 更改,您的测试仍然会通过,尽管真正的应用程序会被破坏。
另一方面,即使测试失败,真正的应用程序仍然会被破坏,因此在这种情况下您无法真正保护您的应用程序。
以下是我们如何为您的代码制作测试客户端:
class TwilioTestClient:
def __init__(self, sid, token):
self.sid = sid
self.token = token
self.messages = TwillioTestClientMessages()
class TwillioTestClientMessages:
self.created = []
def create(self, to, from_, body):
self.created.append({
'to': to,
'from_': from_,
'body': body
})
然后在您的测试中,您可以执行以下操作:
import twilio
# Replace real client with our test client
twilio.Client = TwilioTestClient
// invoke your code
send_sms(phone, content)
assert TwillioTestClientMessages.created == [{
'to': phone,
'from_': settings.DEFAULT_NUMBER,
'body': content
})
这是一种简化的方法,另外您可以使用mock library 来制作测试客户端。
或者您可以修补真正的 twilio 客户端以仅阻止实际的 HTTP 请求并记录参数/模拟响应。
您需要查看 twilio 客户端源代码以找到要模拟的方法(或多个方法),这是我用来模拟的类似方法
通过模拟 requests 库的 Session.request 方法来模拟 facebook 图形响应:
mock_facebook_data = {
'id': 'test_id',
'first_name': 'First Name',
'last_name': 'Last Name'
}
def get_facebook_data(self, method, url, **kwargs):
# Make sure we are mocking the expected request.
assert method == 'get'
assert url == (
'https://graph.facebook.com/me?fields=first_name,id,'
'last_name&access_token={}'.format(facebook_access_token)
)
class ResponseMock:
def __init__(self, data):
self.data = data
self.status_code = 200
def json(self):
return self.data
return ResponseMock(mock_facebook_data)
monkeypatch.setattr('requests.sessions.Session.request', get_facebook_data)
现在,当应用尝试从 facebook API 获取数据时,它会改为获取静态数据,并且该数据将被包装到 ResponseMock 对象中,这是我们从真实请求中获得的最小表示。
还可以查看这篇文章:Unit Testing Your Twilio App Using Python’s Flask and Nose。据我了解,他们使用真正的客户端进行单元测试,但他们也提到了集成的另一面——如何测试从 twilio 端调用的代码。
在这种情况下,您还需要模拟 Twilio 服务器,本文中提供了此类模拟的示例。