Python Module: mock

2013/10/01 Python

mock是什麼

mock is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used.

mock是用於測試的python庫,它允許你在測試時用mock對象替換系統的一部分,並允許斷言這些對象是如何使用的。

Mock is based on the ‘action -> assertion’ pattern instead of ‘record -> replay’ used by many mocking frameworks.

Mock是基於行爲->斷言模式的,而不是許多mocking框架(例如mox)採用的記錄->回放模式。最直接的一個好處就是快,不用跑兩遍,除此此外她還有許多優勢。

mock examples

sudo pip install mock

use start/stop:

1
2
3
4
p = mock.patch("package.module.Class")
m = p.start()
assert m is package.module.Class
p.stop()

use decorator:

1
2
3
4
@mock.patch.object(package.module.Class, 'method')
@mock.patch("package.module.Class")
def test_love(self, cls, method):
    assert cls is package.module.Class

use context:

1
2
with mock.patch("package.module.Class") as m:
    assert m is package.module.Class

something else:

>>> import mock
>>> class A(): pass
...
>>> a = A()
>>> a.method = mock.MagicMock()
>>> a.method.return_value = 3
>>> a.method()
3
>>> a.method.side_effect = Exception()
>>> a.method()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/mock.py", line 955, in __call__
    return _mock_self._mock_call(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1010, in _mock_call
    raise effect
Exception

判断函数中某个参数以某个值被调用:

1
2
3
4
5
@mock.patch.object('path.to.class', 'method_name')
def test_something(self, mocked):
    do_some_thing()
    args, kwargs = mocked.call_args
    self.assertEqual(expected_url, kwargs.get('foo'))

我覺得mock就是無中生有和移花接木,mock的字面也有模擬的意思。mock有如下幾個常見用法

Mock

Mock is a flexible mock object intended to replace the use of stubs and test doubles throughout your code. Mocks are callable and create attributes as new mocks when you access them (there is an exception). Accessing the same attribute will always return the same mock. Mocks record how you use them, allowing you to make assertions about what your code has done to them.

Mock是一個彈性的mock對象,意圖取代打樁子再重複執行代碼的做法。Mock對象是可調用的,並且當你訪問屬性時會創建屬性作爲新的mock對象。訪問同一個屬性將會放回同一個mock對象。Mock對象記錄你是如何使用他們,允許你斷言你的代碼是如何使用她們的。

assert_called_with

assert_called_once_with

assert_any_call

assert the mock has been called with the specified arguments. The assert passes if the mock has ever been called, unlike assert_called_with() and assert_called_once_with() that only pass if the call is the most recent one.

assert_has_calls(calls, any_order=False)

reset_mock()

The reset_mock method resets all the call attributes on a mock object.

called

A boolean representing whether or not the mock object has been called

call_count

An integer telling you how many times the mock object has been called

return_value

side_effect

This can either be a function to be called when the mock is called, or an exception (class or instance) to be raised.

If you pass in a function it will be called with same arguments as the mock and unless the function returns the DEFAULT singleton the call to the mock will then return whatever the function returns. If the function returns DEFAULT then the mock will return its normal value (from the return_value.

call_args

This is either None (if the mock hasn’t been called), or the arguments that the mock was last called with. This will be in the form of a tuple: the first member is any ordered arguments the mock was called with (or an empty tuple) and the second member is any keyword arguments (or an empty dictionary).

call_args_list

This is a list of all the calls made to the mock object in sequence (so the length of the list is the number of times it has been called). Before any calls have been made it is an empty list. The call object can be used for conveniently constructing lists of calls to compare with call_args_list.

method_calls

As well as tracking calls to themselves, mocks also track calls to methods and attributes, and their methods and attributes

mock_calls

mock_calls records all calls to the mock object, its methods, magic methods and return value mocks.

MagicMock

MagicMock is a subclass of Mock with all the magic methods pre-created and ready to use.

MagicMock是Mock的子類,預創建了所有的魔法方法供你玩耍。

patch

The patch() decorators makes it easy to temporarily replace classes in a particular module with a Mock object. By default patch will create a MagicMock for you. You can specify an alternative class of Mock using the new_callable argument to patch.

patch裝飾器使得用Mock對象臨時代替特定模塊的類變成了毛毛雨。patch默認創建一個MagicMock給你。你可以指定一個可選的Mock類給參數new_callable。

patch

多用来patch类,经常使唤start/stop

patch.object

多用来patch对象,常见于上下文管理器,也适用于start/stop

patch.dict

patch.dict can be used to add members to a dictionary, or simply let a test change a dictionary, and ensure the dictionary is restored when the test ends.

patch.dict可以用来增加或修改字典对象,并确保测试结束后恢复原值。

patch.multiple

start, stop, stopall

All the patchers have start and stop methods. These make it simpler to do patching in setUp methods or where you want to do multiple patches without nesting decorators or with statements.

所有的patcher都有start和stop方法。她们简化了在setUp(参见unittest)中打patch,或者在打多个patch而不使用嵌套装饰器或者上下文管理器时的操作。

References

  1. http://www.voidspace.org.uk/python/mock/

License: (CC 3.0) BY-NC-SA

Search

    Table of Contents