Python mock 的使用

使用 mock 对象替换系统的一部分并且能获取它们的使用情况。

具体的说,你可以获取方法/属性的使用情况以及它们的调用参数。也可以指定返回值和设置属性。

思路是将对象设置为 mock 对象,然后根据需要配置 mock 对象,比如返回值、异常等。

设置类方法的返回值并验证被调用过

# -*- coding: utf-8 -*-
from unittest.mock import MagicMock


class ProductionClass:

    def method(self, arg1, arg2, key):
        pass


thing = ProductionClass()
# thing.method 现在指向一个 MagicMock 实例,当这个实例被调用时返回 3
thing.method = MagicMock(return_value=3)
print(thing.method(3, 4, key='value'))  # 3
thing.method.assert_called_with(3, 4, key='value')

设置调用 mock 后的副作用

side_effect 可以是一个函数、iterable 或 exception(类或实例)。

详情见:https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.side_effect

使用装饰器和上下文管理器

上面『设置类方法的返回值并验证被调用过』比较啰嗦且不利用复用,所以改写为装饰器或者
上下文管理器。

装饰器:

# -*- coding: utf-8 -*-
from unittest.mock import patch

from strategy.module import ProductionClass


@patch('strategy.module.ProductionClass.method', return_value=3)
def test(method):
    print(ProductionClass().method(3, 4, key='value'))  # 3
    method.assert_called_with(3, 4, key='value')


test()

上下文管理器:

# -*- coding: utf-8 -*-
from unittest.mock import patch

from strategy.module import ProductionClass


def test():
    with patch.object(ProductionClass, 'method', return_value=3) as mock_method:
        print(ProductionClass().method(3, 4, key='value'))  # 3
        mock_method.assert_called_with(3, 4, key='value')

test()

对于其他对象,比如函数,只需要将 patch 中的路径变为函数的路径即可。

posted @ 2018-05-24 11:24  Jay54520  阅读(1062)  评论(0编辑  收藏  举报