Skip to main content
 首页 » 编程设计

python之使用模拟第三方 API 的 Django/Python 测试

2025年05月04日23bhlsheji

我有一个代码,我正在尝试使用模拟库/python-django 对其进行测试。简要总结一下我的申请:

(第一阶段):客户端使用我的应用公开的 API。映射的 API 函数向第 3 方 API(CaaS 提供商 Tropo)发出 HTTP 连接请求

(阶段 II):Tropo 服务器(第 3 方)用一些 url 返回到我的服务器,我将其映射到函数,该函数向 Tropo 服务器发送另一个请求,在他们这边,对电话号码进行 call()。


我使用 Django 测试客户端只是使用我的 API,它确实运行但问题是它也在 Tropo 上回复以真正调用我提供的数字。所以我想使用 mock() 库但我很少对它的了解。

我所做的是,我看到在 Tropo 的第一阶段将其硬编码到变量 input 之后我得到了什么响应,我也有 expected_output 变量,它也被硬编码看到第二阶段后的输出。

但我想正确构建我的测试框架,在其中我可以在我的测试环境中模拟整个 tropo 库,所有请求都转到这个假库而不是真正的 tropo。但不更改代码。

任何想法或建议。由于我是开发人员,请公开我,这是我尝试做的测试。

由于我没有收到任何回复,我正在尝试提供更多详细信息,说明我到底遇到了什么问题:

假设我的这段代码在一个函数中......

conn     = httplib.HTTPConnection('Some_External_URI') 
 
    headers = {"accept": "application/json", "Content-type":"application/json"} 
    params  = '' 
 
    conn.request('POST', data, params, headers) 
 
    response  = conn.getresponse() 
    payload   = response.read() 

我如何模拟这个特定的连接请求?

请您参考如下方法:

通过在我的代码中模拟类,我能够达到某种程度的测试。

测试.py

    from mock import patch, MagicMock 
    from tropo.conferencing import TropoConferencing 
 
    @patch.object(TropoConferencing, 'sendTriggerCallRequest')  
    def test_ConferenceCreation(self, sendTriggerCallRequest): 
        response_conference = self._createConference(sendTriggerCallRequest) 
        self.assertContains(response_conference, 200) 
 
   def _createConference(self, sendTriggerCallRequest): 
        self._twoParticipants_PhaseI(sendTriggerCallRequest) 
 
        response_conference = self.client.post(self.const.create_conferenceApi , {'title':self.const.title,'participants':self.const.participants}) 
        obj = json.loads(response_conference.content) 
        self.conf_id =  obj['details']['conference_id'] 
 
        try: 
            conference_id =  Conference.objects.get(conferenceId=self.conf_id) 
        except Conference.DoesNotExist: 
            print 'Conference not found' 
 
        # PHASE II 
        self._twoParticipants_PhaseII() 
 
        return response_conference 
 
    def _twoParticipants_PhaseI(self, sendTriggerCallRequest): 
        list_of_return_values= [{'json': {'session_id': 'e85ea1229f2dd02c7d7534c2a4392b32', 'address': u'xxxxxxxxx'}, 'response': True}, 
                            {'json': {'session_id': 'e72bf728d4de2aa039f39843097de14f', 'address': u'xxxxxxxx'}, 'response': True} 
                            ] 
        def side_effect(*args, **kwargs): 
            return list_of_return_values.pop() 
 
        sendTriggerCallRequest.side_effect = side_effect 
 
    def _twoParticipants_PhaseII(self): 
 
        input           = {"session":{"id":"e72bf728d4de2aa039f39843097de14f","accountId":"xxxxx","timestamp":"2013-01-07T18:32:20.905Z","userType":"NONE","initialText":'null',"callId":'null',"parameters":{"phonenumber":"xxxxxxx","action":"create","conference_id":str(self.conf_id),"format":"form"}}} 
        expectedOutput  = '{"tropo": [{"call": {"to": "xxxxxxx", "allowSignals": "exit", "from": "xxxxxxx", "timeout": 60}}, {"ask": {"name": "join_conference", "say": {"value": "Please press one to join conference"}, "choices": {"terminator": "*", "value": "1", "mode": "dtmf"}, "attempts": 1, "timeout": 5, "voice": "Susan"}}, {"on": {"event": "mute", "next": "' + self.const.muteEvent+ str(self.conf_id) + '/xxxxxx"}}, {"on": {"event": "unmute", "next": "/conference/rest/v1/conference/events/unmute/'+ str(self.conf_id) + '/xxxxxxx"}}, {"on": {"event": "hangup", "next": "'+ str(self.conf_id) + '/xxxxxx"}}, {"on": {"event": "continue", "next": "'+ str(self.conf_id) + '/xxxxxx"}}, {"on": {"event": "exit", "next": "'+ str(self.conf_id) + '/xxxxxx"}}, {"on": {"event": "error", "next": "/conference/rest/v1/conference/events/hangup/'+ str(self.conf_id) + '/xxxxxxx"}}, {"on": {"event": "incomplete", "next": "'+ str(self.conf_id) + '/xxxxxxx"}}, {"say": {"value": ""}}]}' 
 
        callbackPayload = json.dumps(input) 
        request = MagicMock() 
        request.raw_post_data = callbackPayload 
 
        response = call(request) 
 
        self.assertEqual(response.content, expectedOutput) 

如您所见,我正在对从 Tropo 获得的响应进行硬编码并将其传递给函数。请让我知道是否有质量检查人员对此类问题有更好的解决方案