3

I am trying to emulate a http server on localhost for faster testing.

ex:

import my_module

class RequestsTestCase(unittest.TestCase):
    def setUp(self):
        # ...
        html = 'hello, world'
        my_server = MyServer(html, 8888)
        my_server.run()
        ...

    def test_my_module_request_phrase(self):
        response = my_module.get_phrase('http://localhost:8888/')
        self.assertEqual(response, 'hello, world')

Is something like this possible using python 3?

10
  • 1
    Depends on what my_server.run() does. If it blocks, then setUp() will not return, and your test(s) won't be executed. Commented Jun 28, 2013 at 18:48
  • 2
    Are you trying to test the client, the server, or an integration scenario? It kind of looks like an integration scenario, in which case you can't really mock out the server and have a legitimate test. If you are doing a client test, you can monkey patch whatever http library you are using to stub out the actual network communication and just return canned responses to the client. If you are testing the server, unless you are actually trying to test the network stack, you can just mock out the request object and feed canned ones in to your models and other code. Commented Jun 28, 2013 at 18:49
  • 2
    Possibly related: Integration testing: Start a blocking server during unittest.setUp before testing it? Commented Jun 28, 2013 at 18:51
  • 1
    In django, you would use django.test.client. But as sr2222 said, it depends on what you are testing. Commented Jun 28, 2013 at 18:53
  • 1
    Unless you have some middleware or something you are trying to test as well, you should be able to get away with mocking out the request object and feeding it in to your models, then validating you get the appropriate response object. You should still at least do some cursory end to end integration testing though, to sanity check the full stack. Commented Jun 28, 2013 at 19:10

2 Answers 2

3

I just wanted to test the response of a request without the need of internet (...)

No problem. You can run your test http server on the same host you run your tests. If you run it in the same process your tests are being run in (which is the case when using unittest and running test server from within setUp() method) then the server has to be run in a separate thread so that it doesn't block your tests. You can take a look how it's done in urllib3 here.

Sign up to request clarification or add additional context in comments.

1 Comment

That link is stale, this seems to be the actual upstream repo: github.com/shazow/urllib3/blob/master/dummyserver/testcase.py
2

First, consider the following aspects:

  • See if it is possible to pull I/O (such as web requests) to the outer layers of your program (google for Clean Architecture). This will make testing much simpler.
  • Make sure you have integration tests in place which test your application in its final context including live web services.

If you are still looking for a tool to easily unit test the remaining web I/O, please consider using the libraries httpretty or responses. With these tools, it is easily possible to specify fake responses including header fields, return codes, and more. The resulting test code will be much cleaner and shorter than what you would write with Python mock alone (or a custom real web server you run concurrently in some other thread).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.