This is the ninth day of my participation in the August More text Challenge. For details, see: August More Text Challenge

What is a mock? For example, if we need to use an interface that is not yet implemented or relies on a third-party service, we can use a mock to simulate the functionality of the interface in order to ensure that the current functionality is developed and tested.

Mock objects are used in Python to control the behavior of mock objects in place of the specified Python objects. The mock module has been incorporated into the Unittest module since Python 3.3 and can be used directly by import.

Basic Use of Mock

A Mock object is an instance of a class in a Mock module. Once created, it can specify return values and set the required properties, as well as assert which methods/properties and their arguments were called.

class Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, **kwargs)
Copy the code

The main arguments of the Mock class are:

  • Name: The name of a mock object, just for identification purposes, can be seen through print.
  • Return_value: Defines the return value of the mock method. You can specify a value (or object) that is returned when the mock object is called.
  • Side_effect: This argument points to a callable object that receives an iterable sequence. You can throw an exception or change the value dynamically. When this parameter is passed, the return_value parameter becomes invalid.
From unittest import mock result1 = mock.mock (name='mock name ') print(result1) mock_value1 = mock.mock (return_value=" return value1 ") Print (mock_value1()) mock_value2 = mock.mock (return_value=" return value2 ",side_effect= [1,2,3]) print(mock_value2()) print(mock_value2()) print(mock_value2())Copy the code

Mock steps are as follows:

  • Import mocks from the Unittest framework
  • Find the object A to replace, which can be A class, function, or class instance
  • Instantiate the mock object and set the behavior of the mock object, such as what value is returned when invoked, what value is returned when a member is accessed, etc.
  • Replace object A with A mock object
  • Call and assert

Mock an undeveloped interface

The ability to mock a dependency

In the real world, we have A scenario where we test module A and then module A relies on A call from module B. We can use A mock to test for normal and exception returns in unit tests.

Here is a way to access Baidu. The visit_baidu() method relies on the return result of send_request.

import requests
​
​
def send_request(url):
    r = requests.get(url)
    return r.status_code
​
​
def visit_baidu():
    url = 'http://www.baidu.com'
    return send_request(url)
Copy the code

Mock to test both normal and exception returns in unit tests

from unittest import mock import unittest import demo class TestReq(unittest.TestCase): def test_request_01(self): # Instantiate the mock object and specify the return value Replace object demo.send_request = mock.mock (return_value='200') print(demo.send_request()) self.assertequal (Demo.visit_baidu (),  '200') def test_request_02(self): # Instantiate the mock object and specify the return value Replace object demo.send_request = mock.mock (return_value='404') print(demo.send_request()) self.assertequal (Demo.visit_baidu (),  '404') if __name__ == '__main__': unittest.main(verbosity=2)Copy the code

Advanced use of mocks

The mock library provides the patch function to simplify the replacement of mock objects. This function returns an instance of the class inside the mock, which controls the scope of the mock and can be used as a decorator or context manager.

Mock. Patch (target, new = DEFAULT, spec = None, create = False, spec_set = None, autospec = None, new_callable = None, * * kwargs)Copy the code

The Mock decorator uses formatting

  • @ patch (” the module name. The method name)”
  • @patch.object(class name, “method name “)

Patch as a decorator, you need to write in the function you want to simulate, and then assign a specific instance of it in the unit test case, and then use return_value to specify the result returned by the simulated function.

Retrofit the above unit test:

from unittest import mock import unittest import demo class TestReq(unittest.TestCase): @mock.patch("demo. Send_request ") def test_request_01(self,mock_request): Mock_request.return_value ='200' self.assertequal (demo.visit_baidu(), '200') @mock.patch("demo.send_request") def test_request_02(self,mock_request): Mock_request.return_value ='404' self.assertequal (demo.visit_baidu(), '404') if __name__ == '__main__': unittest.main(verbosity=2)Copy the code

More mock methods can be found in the official documentation docs.python.org/zh-cn/dev/l…

Reference: Sogou tests Control your Data — Basic Use of Python Mocks