2

I wrote a custom HTTP Handler class to process GET requests sent to a local server. I would like to test the internal functioning of the do_GET method. So far here is what I came up with. This only tests if the do_GET method gets called, nothing more.

Class TestHandler(unittest.Testcase):

    def setUp(self):
        self.mock_request = Mock()

    @patch('http.server.HTTPServer')
    @patch('my_module.Handler.do_GET')
    def test_do_get(self, mock_do_get, mock_http_server):
        """Test if do_GET method gets called"""
        mock_do_get.return_value = "/"
        self.mock_request.makefile.return_value = IO(b"GET /")
        server = Handler(self.mock_request, ('127.0.0.1', 8080), mock_http_server)
        self.assertTrue(mock_do_get.called)
        self.assertEqual(server.do_GET(), "/")

Updated version
Now I know for a fact that the do_GET method get's called when a GET request is sent but I have no way to check the http response.

@patch('http.server.HTTPServer')
def test_do_get_monkey(self, mock_http_server):
    self.mock_request.makefile.return_value = IO(b"GET /test")
    handler = HttpHandler(self.mock_request, ('127.0.0.1', 8080), mock_http_server)
    handler.do_GET = MagicMock(return_value="/")
    handler.do_GET()
    handler.do_GET.assert_called_with()
Hippolyte Fayol
  • 526
  • 1
  • 5
  • 14
  • _I would like to test the internal functioning of the method_ - this is a too broad wish without a context. You can always patch the functions called in `do_GET` and after an HTTP request is processed, assert whether they were called with correct arguments, but other than that it's impossible to answer the question without seeing the code. – hoefling Sep 09 '18 at 12:11
  • @hoefling I took your comment into consideration. Please take a look at the updated version of my question. What I meant by _testing the internal functioning of the method_ simply is that I have several endpoints to which my server reacts to differently, so I'd like to know if the server gives the correct response when a certain endpoint is hit. – Hippolyte Fayol Sep 10 '18 at 09:24
  • Usually, if i need to test the server's response, I start the server in a separate thread and request the URL in question via e.g. `requests`, for example `server = HTTPServer(('127.0.0.1', 8000), Handler); runner = threading.Thread(target=server.serve_forever); runner.start(); time.sleep(3); response = requests.get('http://127.0.0.1:8000/somepath'); self.assertEqual( response.status_code, 200)` etc. Usually, I move the server starting in `setUp` and stopping the server thread in `tearDown`. Sure, this is not a pure unit test anymore, more like a system test, but it does the job pretty well. – hoefling Sep 10 '18 at 09:35
  • For pure unit testing, you may find the answer in this question useful: [Python: How to unit test a custom HTTP request Handler?](https://stackoverflow.com/questions/25369068/python-how-to-unit-test-a-custom-http-request-handler) – hoefling Sep 10 '18 at 09:37
  • Thanks for your help. Starting the server in a separate thread was my first idea but I also thought it wasn't a pure unit test per say. The code that I posted at in the first place was inspired from the question you've mentioned but there is no way to get the response. I think I will go with the two options to have everything covered. – Hippolyte Fayol Sep 10 '18 at 13:36

0 Answers0