A memorandum about Python mock

The other day I was troubled by Python Mock, so I will leave a memorandum.

Official document for the time being

[unittest.mock --- mock object library] (https://docs.python.org/ja/3/library/unittest.mock.html) [unittest.mock --- Introduction] (https://docs.python.org/ja/3/library/unittest.mock-examples.html)

It was officially written that I was worried about 2 hours. The formula is great

mock requests.get

tori01.py


import requests

def get_qiita(url):
    response = requests.get(url)
    return response

Just get with url and return the returned response

test_tori01.py


import unittest
from mock import Mock, patch

import tori01

class TestTori01(unittest.TestCase):

    @patch("tori01.requests.get")
    def test_get_response(self, requests_get):
        requests_get.return_value.status_code = 200

        res = tori01.get_response("mock.url")
        self.assertEqual(res.status_code, 200)

Assertion check with status code This time based on these codes

around patch

Since requests is imported in tori01.py Patched with @ patch ("tori01.requests.get")

If this is tori01.py and requests.get is imported It will not be patched unless you do @ patch ("tori01.get ")

tori01.py


#Changed from import requests
from requests import get

def get_response(url):
    response = get(url)
    return response

test_tori01.py


import unittest
from mock import Mock, patch

import tori01

class TestTori01(unittest.TestCase):

    # @patch("tori01.requests.get")Change from
    @patch("tori01.get")
    def test_get_response(self, requests_get):
        requests_get.return_value.status_code = 200

        res = tori01.get_response("mock.url")
        self.assertEqual(res.status_code, 200)

If you want to mock `requests` instead of` requests.get` (which is legitimate)

test_tori01.py


import unittest
from mock import Mock, patch

import tori01

class TestTori01(unittest.TestCase):

    # @patch("tori01.requests.get")Change from
    #Argument naming is also requests.Change from get to requests
    @patch("tori01.requests")
    def test_get_response(self, requests):
        # requests_get.return_value.status_code =Changed from 200
        requests.get.return_value.status_code = 200

        res = tori01.get_response("mock.url")
        self.assertEqual(res.status_code, 200)

Call a function

You can check the argument when it is called.

test_tori01.py


import unittest
from mock import Mock, patch

import tori01

class TestTori01(unittest.TestCase):

    @patch("tori01.requests.get")
    def test_get_response(self, requests_get):

        #Create a function that returns a mock so that it will be called.
        def requests_get_mock(url):
            return Mock(status_code = 200, url = url)

        requests_get.side_effect = requests_get_mock

        res = tori01.get_response("mock.url")
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.url, "mock.url")

You can check with ʻassert_called_with` without doing this roundabout thing. There are various other assert systems

test_tori01.py


import unittest
from mock import Mock, patch

import tori01

class TestTori01(unittest.TestCase):

    @patch("tori01.requests.get")
    def test_get_response(self, requests_get):
        requests_get.return_value.status_code = 200

        res = tori01.get_response("mock.url")
        self.assertEqual(res.status_code, 200)
        requests_get.assert_called_with("mock.url") #add to

Change the return value depending on the argument

test_tori01.py


import unittest
from mock import Mock, patch

import tori01

class TestTori01(unittest.TestCase):

    @patch("tori01.requests.get")
    def test_get_response(self, requests_get):

        vals = {"mock.url":200, "error_mock.url":404}
        def requests_get_mock(val):
            return Mock(status_code = vals[val])

        requests_get.side_effect = requests_get_mock

        res = tori01.get_response("mock.url")
        res_error = tori01.get_response("error_mock.url")
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res_error.status_code, 404)

You can also throw an exception

test_tori01.py


import unittest
import requests
from mock import Mock, patch

import tori01

class TestTori01(unittest.TestCase):

    @patch("tori01.requests.get")
    def test_get_response(self, requests_get):

        # side_If you set an exception class for effect, an exception will be thrown
        requests_get.side_effect = requests.HTTPError

        with self.assertRaises(requests.HTTPError):
            tori01.get_response("mock.url")

I may add it or write part 2

Magic Mock ...

Recommended Posts

A memorandum about Python mock
A memorandum about correlation [Python]
A note about mock (Python mock library)
A memorandum about matplotlib
A memorandum about the Python tesseract wrapper library
About python beginner's memorandum function
A note about [python] __debug__
Python memorandum
Python Memorandum 2
Python memorandum
python memorandum
python memorandum
Python memorandum
python memorandum
Python memorandum
Python: A Note About Classes 1 "Abstract"
[Python] A memorandum of beautiful soup4
About python slices
Python basics memorandum
Python pathlib memorandum
Python memorandum (algorithm)
About python yield
About python, class
Memorandum of python beginners About inclusion notation
A Java programmer studied Python. (About type)
A memorandum of understanding about django's QueryDict
About python decorators
A story about Python pop and append
Python memorandum [links]
Python Basic Memorandum Part 3-About Object Orientation-
About python reference
About Python decorators
[Python] About multi-process
Memorandum about validation
About February 02, 2020 * This is a Python article.
A memorandum of python string deletion process
A Java programmer studied Python. (About functions (methods))
A Java programmer studied Python. (About the decorator)
A memorandum of calling Python from Common Lisp
Python variadic memorandum when inheriting a defined class
A memo about writing merge sort in Python
A note about the python version of python virtualenv
Data analysis in Python: A note about line_profiler
A memorandum for touching python Flask on heroku
A story about modifying Python and adding functions
About Python for loops
Summary about Python scraping
Python memorandum numbering variables
A * algorithm (Python edition)
About function arguments (python)
[Python] Take a screenshot
python memorandum (sequential update)
Create a Python module
A python lambda expression ...
[Python] Memo about functions
Summary about Python3 + OpenCV3
About Python, for ~ (range)
Python memorandum (personal bookmark)
Daemonize a Python process
About Python3 character code
[Python] Memo about errors