1

I am writing a small Python flask app whose sole purpose is to make a request to get a web page at one specific URL (always the same) and parse a section of the content. The app surfaces two endpoints, /games/ and /games/. If the former, it returns info for all games listed on the web page, if the latter, just for that one game.

I have been asked to write unit tests and treat the web page as the data, but I dont think the test should hit the target URL through the network, so I want to make it so the web page is read from a file that I produced with curl and use that as the source.

What I am struggling with is how to insert the data into the response object from a requests.get() call. I've gone through pages and pages of examples of how to do mocking, but there isn't a clear, simple explanation of how to do this.

That's all I need to do. I have a file with the html from the original web site and I want the response data to come from the file, not the web site.

Any ideas?

UPDATE:

I figured it out on my own:

I separated out the line that calls requests.get into a function get_html then I mocked it in the test app.

@mock.patch ('myflaskApp.get_html')
def test_get_html(get_html):
  theSession = requests.Session()
  theSession.mount('file://', FileAdapter())
  resp = theSession.get('file://'+os.getcwd()+'/mytestdata.html')

And then I simplified things even more by realizing I don't need to mock anything. I changed get_html() to check if the app.testing flag is true and have it load the adapter that way otherwise do a regular get.

Juan Jimenez
  • 443
  • 4
  • 18

1 Answers1

1

You can use unittest.mock library to intercept requests and test them like this:

try:
    from unittest import mock
except ImportError:
    import mock  # noqa

Next you take a function and substitute its call:

@mock.patch('requests.get')
def test_fetch(self, mock_get):
    # perform some actions then check it was called with correct number of parameters
    self.assertEqual(len(mock_get.call_args_list), 3)
    # and right parameter values
    self.assertIn(mock.call('http://someurl.com/test.json'), mock_get.call_args_list)

Here're details - https://docs.python.org/3/library/unittest.mock.html

Eugene Lisitsky
  • 12,113
  • 5
  • 38
  • 59
  • This is very confusing, because you're telling me I should try something but not *where*. Does this go in the Flask app? in a separate testing app? What is "telegram.bot."? Too many assumptions of knowledge here... :( – Juan Jimenez Oct 06 '17 at 17:03
  • Sorry this was copy-pasted from one of old projects. I'll describe better. – Eugene Lisitsky Oct 06 '17 at 17:07
  • Ok, but *where* do I put this? In the Flask app? In a separate app? – Juan Jimenez Oct 06 '17 at 18:41
  • I figured it out. What I really needed to do was mock the function and then use requests-file and its fileadapter. thanks for the tip that led me to the answer. :) – Juan Jimenez Oct 08 '17 at 16:40
  • 1
    Sorry haven't found better example. Glad to hear this was usable :)) Good luck ) – Eugene Lisitsky Oct 08 '17 at 17:19