Python: How to unit test a custom HTTP request Handler?

前端 未结 3 1334
自闭症患者
自闭症患者 2021-02-20 17:12

I have a custom HTTP request handler that can be simplified to something like this:

# Python 3:
from http import server

c         


        
3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-02-20 18:14

    Expanding on the answer from jakevdp, I managed to be able to check the output, too:

    try:
        import unittest2 as unittest
    except ImportError:
        import unittest
    try:
        from io import BytesIO as IO
    except ImportError:
        from StringIO import StringIO as IO
    from server import MyHandlerSSL  # My BaseHTTPRequestHandler child
    
    
    class TestableHandler(MyHandlerSSL):
        # On Python3, in socketserver.StreamRequestHandler, if this is
        # set it will use makefile() to produce the output stream. Otherwise,
        # it will use socketserver._SocketWriter, and we won't be able to get
        # to the data
        wbufsize = 1
    
        def finish(self):
            # Do not close self.wfile, so we can read its value
            self.wfile.flush()
            self.rfile.close()
    
        def date_time_string(self, timestamp=None):
            """ Mocked date time string """
            return 'DATETIME'
    
        def version_string(self):
            """ mock the server id """
            return 'BaseHTTP/x.x Python/x.x.x'
    
    
    class MockSocket(object):
        def getsockname(self):
            return ('sockname',)
    
    
    class MockRequest(object):
        _sock = MockSocket()
    
        def __init__(self, path):
            self._path = path
    
        def makefile(self, *args, **kwargs):
            if args[0] == 'rb':
                return IO(b"GET %s HTTP/1.0" % self._path)
            elif args[0] == 'wb':
                return IO(b'')
            else:
                raise ValueError("Unknown file type to make", args, kwargs)
    
    
    class HTTPRequestHandlerTestCase(unittest.TestCase):
        maxDiff = None
    
        def _test(self, request):
            handler = TestableHandler(request, (0, 0), None)
            return handler.wfile.getvalue()
    
        def test_unauthenticated(self):
            self.assertEqual(
                    self._test(MockRequest(b'/')),
                    b"""HTTP/1.0 401 Unauthorized\r
    Server: BaseHTTP/x.x Python/x.x.x\r
    Date: DATETIME\r
    WWW-Authenticate: Basic realm="MyRealm", charset="UTF-8"\r
    Content-type: text/html\r
    \r
    Authentication Failed

    Authentication Failed

    Authentication Failed. Authorised Personnel Only.

    """ ) def main(): unittest.main() if __name__ == "__main__": main()

    The code I am testing returns a 401 Unauthorised for "/". Change the response as appopriate for your test case.

提交回复
热议问题