Python中Mock和MagicMock的区别

Python的unittest.mock模块中提供了两个主要的mock类,分别是MockMagicMock.

先看一下官方文档的定义:

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类似。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值