Python的unittest.mock模块中提供了两个主要的mock类,分别是Mock和MagicMock.
先看一下官方文档的定义:
MagicMock is a subclass of Mock with all the magic methods pre-created and ready to use.
其实已经很清楚了,MagicMock是Mock的子类,并且预先创建了全部magic method的mock。
也就是说,如果不需要mock magic method,两者使用起来并没有什么分别。
来看个例子,先定义个类,里面只有一个成员方法,返回10倍的数值:
class Person:
def get_10_times_value(self, value)
return 10 * value
使用Mock类来mock掉这个成员方法:
def test_should_mock_get_10_times_value_with_Mock(self):
p = Person()
p.get_10_times_value = Mock(return_value=100)
self.assertEqual(p.get_10_times_value(), 100)
使用MagicMock类来mock:
def test_should_mock_get_10_times_value_with_MagicMock(self):
p = Person()
p.get_10_times_value = MagicMock(return_value=100)
self.assertEqual(p.get_10_times_value(), 100)
两者没有任何区别,都成功了mock了成员方法。
再看下两者的区别:
def test_should_raise_exception(self):
m = Mock()
list(m)
TypeError: 'Mock' object is not iterable
因为使用Mock类时,默认不会创建__iter__这个magic method的mock,所以报错。
如果想mock __iter__这个方法,得自己去做,如下:
def test_should_mock_magic_method_with_Mock(self):
m = Mock()
m.__iter__ = Mock(return_value=iter([]))
self.assertEqual(list(m), [])
而使用MagicMock类时默认就会mock掉所有的magic method,所以不需要自己mock,__iter__默认是空数组:
def test_should_mock_magic_method_with_MagicMock(self):
m = MagicMock()
self.assertEqual(list(m), [])
因为已经默认创建了magic method的mock,所以可以直接使用return_value属性来改变值:
def test_should_mock_magic_method_with_MagicMock(self):
m = MagicMock()
m.__iter__.return_value = [1, 2, 3]
self.assertEqual(list(m), [1, 2, 3])
其他magic method类似。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。