简体   繁体   English

Python 3 Pytest:如何模拟请求 urlopen 响应和标头?

[英]Python 3 Pytest: How to mock request urlopen response and headers?

I have broken my code down into separate functions for unit testing.我已将代码分解为用于单元测试的单独函数。 I am trying to pick up Pytest testing framework and so far only know the basics.我正在尝试使用 Pytest 测试框架,到目前为止只知道基础知识。

I don't actually want to send a request to the internet -- this would be a fruitless test since I'd only be testing the urllib library anyway.我实际上并不想向互联网发送请求——这将是一个徒劳的测试,因为无论如何我只会测试urllib库。 I do, however, want to test how the response is handled.但是,我确实想测试响应的处理方式。

I have this function to make the request我有这个功能来提出请求

def request_url(url):
    return request.urlopen(url)

And then I am checking the content type:然后我正在检查内容类型:

def get_document_type(req):
    """ checks if document is html or plain text """
    doc_type = req.info().get_content_type()
    if doc_type == "text/html":
        return "html"
    elif doc_type == "text/plain":
        return "txt"
    else: 
        return error_message["unsupported_document_type"]

Then I will need to test and I will need to mock each outcome.然后我需要测试,我需要模拟每个结果。 If this was Node.js I could use something like rewire or a sinon stub.如果这是 Node.js,我可以使用 rewire 或 sinon 存根之类的东西。

def get_content(req):
    doc_type_response = get_document_type(req)
    if doc_type_response == "html":
        # handle html content
    elif get_type_response == "txt":
        # handle plain text
    else:
        return doc_type_response

This unit test works but I don't want to make the real call.这个单元测试有效,但我不想打真正的电话。

def test_request_url():
    url = request_url(url_to_try).info().get_content_type() 
    assert url == "text/plain"

Does anybody know the best way to do this please?有人知道这样做的最佳方法吗?

There is a package requests-mock https://pypi.org/project/requests-mock/ which can be used for mocking API calls but for requests library.有一个包 requests-mock https://pypi.org/project/requests-mock/可用于模拟 API 调用,但用于请求库。 This is an example with headers/text这是一个带有标题/文本的示例

import unittest
import requests_mock
import requests

class TestImplementations(unittest.TestCase):

    @requests_mock.mock()
    def test_get_project(self, mock_for_requests):
        API_URL = "https://someapi.com"

        #mocking your request(s)
        expected_headers = {'Content-Type': 'text/plain'}
        expected = 'some_text'
        mock_for_requests.get(API_URL + "/someendpoint", headers=expected_headers, text=expected)

        #running your code with requests
        response = requests.get(API_URL + "/someendpoint")

        #comparing output
        self.assertEqual(response.headers, expected_headers)
        self.assertEqual(response.text, expected)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM