1

I have an endpoint on my localhost to get time from different time zones. I type the time zone code in the URL and it shows the time for that time zone. This program uses an external API to get the time. I need to mock this call to the external API and return a hard coded value.

I was following this tutorial from Here

With the program to be mocked as:

import requests

class Blog:
    def __init__(self, name):
        self.name = name

    def posts(self):
        response = requests.get("https://jsonplaceholder.typicode.com/posts")

        return response.json()

    def __repr__(self):
        return '<Blog: {}>'.format(self.name)

And the test code as:

from unittest import TestCase
from unittest.mock import patch, Mock


class TestBlog(TestCase):
    @patch('main.Blog')
    def test_blog_posts(self, MockBlog):
        blog = MockBlog()

        blog.posts.return_value = [
            {
                'userId': 1,
                'id': 1,
                'title': 'Test Title',
                'body': 'Far out in the uncharted backwaters of the unfashionable  end  of the  western  spiral  arm  of  the Galaxy\ lies a small unregarded yellow sun.'
            }
        ]

        response = blog.posts()
        self.assertIsNotNone(response)
        self.assertIsInstance(response[0], dict)

Now my question is does this example actually mock the call the external source, which in this case is the JsonPlaceholder. And does this test code hard code the response for the original program?

Sorry if this a simple question, I am struggling to find an example I can actually understand, the python docs are way over my head.

Lin Du
  • 88,126
  • 95
  • 281
  • 483
dan
  • 21
  • 2
  • Here is a post on this topic, https://stackoverflow.com/questions/15753390/how-can-i-mock-requests-and-the-response – sushanth Jul 17 '20 at 17:36
  • Does this answer your question? [How can I mock requests and the response?](https://stackoverflow.com/questions/15753390/how-can-i-mock-requests-and-the-response) – D Malan Aug 03 '20 at 21:34

1 Answers1

0

You are testing blog.posts() method. So you should mock requests.get() and response.json() methods and their returned values.

E.g.

main.py

import requests


class Blog:
    def __init__(self, name):
        self.name = name

    def posts(self):
        response = requests.get("https://jsonplaceholder.typicode.com/posts")
        return response.json()

    def __repr__(self):
        return '<Blog: {}>'.format(self.name)

test_main.py:

import unittest
from unittest import TestCase
from unittest.mock import patch, Mock
from main import Blog


class TestBlog(TestCase):
    @patch('main.requests')
    def test_blog_posts(self, mock_requests):
        mock_requests.get.return_value.json.return_value = [
            {
                'userId': 1,
                'id': 1,
                'title': 'Test Title',
                'body': 'Far out in the uncharted backwaters of the unfashionable  end  of the  western  spiral  arm  of  the Galaxy\ lies a small unregarded yellow sun.'
            }
        ]
        blog = Blog('teresa teng')
        response = blog.posts()
        self.assertIsNotNone(response)
        self.assertIsInstance(response[0], dict)
        mock_requests.get.assert_called_once_with('https://jsonplaceholder.typicode.com/posts')
        mock_requests.get.return_value.json.assert_called_once()


if __name__ == '__main__':
    unittest.main()

unit test result with coverage report:

.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Name                                      Stmts   Miss  Cover   Missing
-----------------------------------------------------------------------
src/stackoverflow/62959109/main.py            9      1    89%   13
src/stackoverflow/62959109/test_main.py      15      0   100%
-----------------------------------------------------------------------
TOTAL                                        24      1    96%
Lin Du
  • 88,126
  • 95
  • 281
  • 483