【问题标题】:Python Mocking a request for a bearer token?Python模拟对不记名令牌的请求?
【发布时间】:2021-05-18 15:21:19
【问题描述】:

我试图弄清楚如何在 python 中模拟我对不记名令牌的请求。 我有一堂课:

class grab_apitokens(object):

    def __init__(self, consumer_key, first_api_url, second_api_user, second_api_password, second_api_url):
        self.consumer_key = consumer_key
        self.second_api_user = second_api_user
        self.second_api_password = second_api_password
        self.first_api_url = first_api_url
        self.second_api_url = second_api_url

    def logintofirstsite(self):  
        b64val = base64.b64encode(self.consumer_key.encode()).decode()
        headers = {"Authorization": "Basic %s" % b64val}
        data = {'grant_type': 'client_credentials', 'validity_period': '3600'}
        try:
            response = requests.post(self.first_api_url, headers=headers, data=data)
            decodedresponse = json.loads(response.content.decode())
            access_token = decodedresponse['access_token']
            return access_token
        except:
            return None
            
    def logintosecondsite(self):
        header = {"accept": "application/json", "Content-Type": "application/x-www-form-urlencoded"}
        logindata = {'grant_type': 'password',
                     'username': "" + self.second_api_user + "", 'password': "" + self.second_api_password + ""
                     }
        try:
            returnedfromsite = requests.post(self.second_api_url + '/api/V1/token', 
headers=header, data=logindata)
            return returnedfromsite.json()['access_token']
        except:
            return None

我不知道如何模拟请求调用以及它在 Python 中的样子。

我的测试目前看起来像:

class MyTestCase(unittest.TestCase):



    def setUp(self) -> None:       # PROBLEM BEGINS HERE
        self.grab_apitokens = grab_apitokens(actual_key, actual_site1, actual_user, actual_pass, actual_2nd_site)

    @patch('grab_apitokens.requests.get')
    def test_login(self, mock_get):
        mock_get.return_value.ok = True
        response = self.grab_apitokens.logintosite()
        assert_is_not_none(response)
        # self.assertEqual(True, False)



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

如何模拟 requests.post 功能?

【问题讨论】:

  • 是否在test_login 中创建grab_apitokens 对象并删除setUp 选项?这样您就可以使用所需的任何参数调用 init。
  • 我不是很关注,但我们可以做任何我们需要的事情。我只是把它放在那里,因为它可以让我不必为每个测试单独调用它。
  • 如果您需要专门为每个测试模拟它,那么我会在每个测试中声明它。此外,如果您需要为不需要模拟 init 的所有测试设置相同的 url,只需在 setUp 中创建对象时使用测试 url,因为 init 不进行任何调用,它只是将一些字段设置为静态值
  • 我不确定我们是否仍然在同一页面上。这里的目标是消除对设置类中那些实际值的需求。我需要检查为该类编写的函数是否可以正常工作,而无需进行外部 API 调用。不知何故,我需要伪造我在 setUp 中输入的数据,同时让方法变得不明智。

标签: python python-3.x unit-testing python-unittest


【解决方案1】:

在一位好导师的帮助下,我发现我的方法全错了。以下是我最终完成的单元测试:

class MyTestCase(unittest.TestCase):


    def setUp(self) -> None:
        self.grab_apitokens = grab_apitokens("complete","gibberish","it really doesnt","matter","what is","in","here")

    @patch('grab_apitokens.requests.posts')
    def test_login(self, mock_get):
        mock_json = {'token': 'foo'}
        mock_get.return_value = Mock(ok=True)
        mock_get.return_value.json.return_value = mock_json
        mock_get.return_value.content = b'{"token": "foo"}'
        response = self.grab_apitokens.logintofirstsite()
        assert_equal(response, "foo")



if __name__ == '__main_

要了解它的作用,我需要知道我们真正模拟的不是方法 logintofirstsite(),我们模拟的是 requests.post 在方法中做出的响应。使用 mock_get,我们将 requests.posts 注入始终为: {'token': 'foo'} 。所以之后的一切

response = requests.post(self.first_api_url, headers=headers, data=data)

in logintofirstsite() 是我真正要测试的。即:

            decodedresponse = json.loads(response.content.decode())
            access_token = decodedresponse['token']
            return access_token

requests.post 调用之前的设置一点都不重要。由于 with {'token': 'foo'} 是我的 requests.post 调用返回的内容,因此该位逻辑之后的返回值是 'foo',因此 MyTestCase 中的 assert_equal 会通过。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-11
    • 2020-01-24
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2021-08-02
    • 2017-03-20
    • 1970-01-01
    相关资源
    最近更新 更多