首页 > 解决方案 > 在我的课堂上模拟多个 API 调用并编写测试

问题描述

所以,我试图在我的课堂上模拟一些 API,代码看起来像这样。

import requests
class myclass:
  def A(self, data):
    response = requests.get("some_url", params)
    if response.data["has_value"]:
      new_response = requests.get("some_url", params)
      **do some validation on data recieved**
  def B(self, data):
    response = requests.get("some_url", params)
    **do some validation on data recieved**
  def _run(self):
    **some code**
    self.A(data)
    self.B(data)

m = myclass()
m.run()

我正在尝试测试这些并需要一些帮助。在进行验证时,我们更改了数据中的一些字段,我必须验证数据是否正确。如何才能做到这一点?谢谢你。

标签: pythontestingpython-requestspython-unittest

解决方案


unittest这是使用包的单元测试解决方案Python 3.7.5

myclass.py

import requests


class MyClass:
    def A(self, data):
        params = None
        response = requests.get("some_url", params)
        if response.data["has_value"]:
            new_response = requests.get("some_url", params)
            print(new_response)

    def B(self, data):
        params = None
        response = requests.get("some_url", params)

    def _run(self):
        data = {}
        self.A(data)
        self.B(data)

test_myclass.py

import unittest
from myclass import MyClass, requests
from unittest.mock import MagicMock, patch
from collections import namedtuple


class testMyClass(unittest.TestCase):

    @patch('builtins.print')
    @patch.object(requests, 'get')
    def test_A(self, mocked_get, mocked_print):
        Response = namedtuple('Response', ['data'])
        response = Response(data={'has_value': True})
        mocked_get.side_effect = [response, 'new response']
        myclass = MyClass()
        data = {}
        myclass.A(data)
        mocked_get.assert_called_with('some_url', None)
        self.assertEqual(mocked_get.call_count, 2)
        mocked_print.assert_called_with('new response')

    def test_B(self):
        # same as test_A, you can do it.
        self.assertEqual(1, 1)

    def test__run(self):
        myclass = MyClass()
        myclass.A = MagicMock()
        myclass.B = MagicMock()
        myclass._run()
        myclass.A.assert_called_with({})
        myclass.B.assert_called_with({})


if __name__ == '__main__':
    unittest.main()

带有覆盖率报告的单元测试结果:

...
----------------------------------------------------------------------
Ran 3 tests in 0.002s

OK
Name                                         Stmts   Miss  Cover   Missing
--------------------------------------------------------------------------
src/stackoverflow/60910413/myclass.py           15      2    87%   13-14
src/stackoverflow/60910413/test_myclass.py      27      0   100%
--------------------------------------------------------------------------
TOTAL                                           42      2    95%

推荐阅读