For testing I use pytest so it would be great if you suggest something pytest specific.
I have some code which uses the requests library. What it does is basically simple POST/GET requests for logging in, parsing data, etc.
Surely I want to test that code locally without doing any actual HTTP requests.
A monkeypatch funcarg could be the solution, but I think that mocking request.get(...) calls or directly pythons's urllib isn't good, because, for example, there are functions which do more than one HTTP request inside , so I can't just mock the request.get("anyURL") with a simple lambda *args, **kwaargs: """<html>response</html>""".
There are different URLs which should return different content. Sometimes it should be based on POST/GET data. Also I have no idea how will requests.session behave in case of direct mocking. Besides that how to emulate session termination? How to emulate a connection failure?
So in the end in my opinion it's quite hard to use monkey patching here. At least I am not able to write a good mocking function which will take into account everything. Also if I choose to mock urllib directly and someday requests library starts using something different all my tests will fail.
So the best way I think is to use actual HTTP server which turns on on a test run, and if possible takes into account pytest's scopes, etc (so it's a funcarg). While googling I found only two solutions:
The first one sets up the HTTP server and serves predefined content over a specific URL. Definitely that does not work for me, because as I mentioned some functions which I intend to test do several requests so all inner HTTP requests.get() will get the same answer. Bad.
The second one as far a I see has the same problem. Or at least do not understand how to use it.
The third option could be writing a small Flask based service, but I guess I'll run into a problem that things I use in tests should be tested as well which is a bad practice.
unittest.mock(ormockfor python pre 3.4) for patching and mockingurllib.requests()is exactly what you need: you can test if your app call it correctly and the behavior onrequests()return values.urlliband mock it even if it do several request (you can useside_effectproperty of mocks objects to play with that cases). If you try to test your application by mock the server you will have a lot of issue to track your bugs because your sense points will be too far from your bugs. Sure, you need even integration tests that use real server and realurllibcalls but not for all your expected behaviors. You are free to experiment to mock the server but i think you will know the awful truth :)side_effectis very simple to do: please spend 2 minutes to read the documentation voidspace.org.uk/python/mock/mock.html#mock.Mock.side_effect . Write a callable that map a dictionary do the work. You can usemockas is without unittest.