python-test mock

1. why we use patch

Isolation:
When testing a function, you want to focus on the logic of that function without interference from other parts of the system. By patching dependencies, you ensure that your tests are not affected by other components’ behavior.

Avoid External Dependencies:
If a function relies on external resources (e.g., a database, a web service), patching allows you to simulate these dependencies without making actual calls. This makes tests faster and more reliable.

Control Over Function Behavior:
You can define the return value of a patched function to test different scenarios, including edge cases and error conditions, which might be hard to reproduce with the actual function.

Ensuring Correct Interactions:
Patching allows you to verify that a function interacts with its dependencies in the expected way. You can check that certain methods are called with specific arguments.

2 example

assume you have this module structure:

project/
├── math_operations.py
└── test_math_operations.py

here are the code for these two file

# math_operations.py

def external_service(a, b):
    # Imagine this function makes a network call to an external service
    return a + b

def add(a, b):
    return external_service(a, b)

# test_math_operations.py

import unittest
from unittest.mock import patch
from math_operations import add

class TestMathOperations(unittest.TestCase):
    
    @patch('math_operations.external_service')
    def test_add(self, mock_external_service):
        # Arrange
        mock_external_service.return_value = 10
        
        # Act
        result = add(3, 7)
        
        # Assert
        mock_external_service.assert_called_once_with(3, 7)
        self.assertEqual(result, 10)

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

how to run

python -m unittest test_math_operations.py

3 explanation

  • mock_external_service is the mock object that replaces the external_service function in the math_operations module.
  • This mock object allows you to define custom behavior for external_service during the test.
  • mock_external_service.return_value = 10 specifies that whenever external_service is called, it should return 10.
  • mock_external_service.assert_called_once_with(3, 7) checks that external_service was called exactly once with the arguments 3 and 7.
  • If external_service was not called, or was called with different arguments, or was called more than once, this assertion will fail, causing the test to fail.

note: for other method like assert_called_once_with, you can check unittest.mock.py to get more.

4 Parameters of patch

patch(
        target, new=DEFAULT, spec=None, create=False,
        spec_set=None, autospec=None, new_callable=None, *, unsafe=False, **kwargs
    )

target:

This is the dotted path to the object you want to patch. It should be a string in the format ‘module.ClassName’ or ‘module.function_name’. For example, ‘math_operations.external_service’.
new (default: DEFAULT):

This specifies the new object that will replace the target during the patch. If not specified, a MagicMock will be used as the default replacement.

spec (default: None):

This allows you to specify a class or instance that the mock should emulate. The mock will only allow attributes that exist on the specified class or instance, which helps to prevent errors due to incorrect attribute usage.

create (default: False):

If True, patch will create the attribute if it does not exist. This is useful for dynamically adding attributes to objects.

spec_set (default: None):

Similar to spec, but stricter. Once the attributes are set, they cannot be changed, which helps in locking down the mock to a specific set of attributes.

autospec (default: None):

If True, patch will use the function or class signature to create a more accurate mock. This ensures that the mock has the same signature as the original object, making it more realistic and preventing mistakes.

new_callable (default: None):

This is a callable that returns the new object to be used as the mock. If provided, this will override the default MagicMock.

unsafe (default: False):

If True, this disables safety checks that are normally performed. For instance, if you need to mock an attribute that normally cannot be modified, setting unsafe=True would allow you to bypass this restriction. Use with caution as it can lead to hard-to-debug issues.

**kwargs:

Additional keyword arguments that are passed to the mock object constructor. This allows for more customization of the mock object.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值