美文网首页
Python中的模块学习之mock模块

Python中的模块学习之mock模块

作者: summer_1a77 | 来源:发表于2019-04-01 14:41 被阅读0次

    学习Python也有一段时间了,然而对Python中的单元测试模块这些并不是很懂,刚好,今天有点时间,就将mock模块进行学习并整理,下边进行分享:

    先来看一下本文的整体框架:

    为什么要使用mock?

    场景模拟1:比如有A和B两个模块,A模块中有调用到B模块的方法,但是很不幸,B模块中被A模块调用的方法由于一定的原因需要被修改,然而我们又不想让影响A模块的功能测试,所以就用到了单元测试模块unittest中的mock模块;mock模块就是模拟出一个假的B模块;

    场景模拟2:有时需要为单元测试的初始设置准备一些其他的资源,但是这些资源又不太经常使用或者是使用起来比较笨拙,此时我们就可以定义一个mock对象来模拟一个需要使用的资源;mock对象用于代替测试的准备资源;

    下边先来看一下mock对象都有哪些属性?知道这些属性,后续使用mock才会得心应手;

    网上看到有人将mock的方法进行了分类:

    一、构造器

    init是mock对象的构造器,name是mock对象的唯一标识;spec设置的是mock对象的属性,可以是property或者方法,也可以是其他的列表字符串或者其他的python类;return_value设置的是,当这个mock对象被调用的时候,显示出的结果就是return_value的值;side_effect是和return_value是相反的,覆盖了return_value,也就是说当这个mock对象被调用的时候,返回的是side_effect的值,而不是return_value。

    举例说明:

    1.name参数:

    从上述的举例中可以看出,name标识了唯一的一个mock(print的时候,后边会显示ID)。

    2.return_value参数:

    a.指定的是某个值:

    从上边的例子可以看出,当我们调用mock对象的时候,显示的就是return_value的值(也就是说mockObj是带有一定的功能的);

    b.指定的是某个类的对象:

    3.side_effect参数:

    a.指定的参数的值是异常

    从上边的例子可以看出,当side_effecr被设置的时候,return_value就被屏蔽了,不起作用了,上边side_effect被设置的是一个异常。

    b.指定的参数的值是一个list或者tuple:

    插入:到这里居然想起了python中的生成器函数,yield的用法有点像return,返回的是一个生成器函数,当调用这个函数的时候,写在函数中的代码并没有真正执行,他只是返回了一个生成器。

    看下边的例子:通过下边的函数创建出了一个生成器之后,每次执行next操作,都会返回一个值,当返回完的时候,就会抛出异常。

    4.spec参数:

    a.指定的是属性组成的list

    b.指定的是一个类属性:

    正如文章开头所说,spec设置的是mock对象的属性,所以,这下,mock就有了3个属性了。

    二、mock的断言:

    1.assert_called_with(*argSeq, **argKW):检查mock方法是否获得了正确的参数;当至少有一个参数有错误的值或者类型时,当参数的个数出错时,当参数的顺序不正确时,这个断言就会发生错误。

    参数个数错误的举例,这里就不给出了~~上边,mockFoo对象调用了fun2函数多次,但是有些时候,我们只是希望mock对象调用某个方法一次,所以,就有了下边的一个断言:

    2.assert_called_once_with(*argSeq, **argKW)这个断言,当某个方法被多次调用的时候,它就会报错,看下边的例子:

    注明:下边这个例子是接着上边的例子的,看上边,上边的例子中我们已经调用了fun1一次了,所以,下边的例子提示断言错误,并且还有次数显示呢~

    3.assert_any_call()用于检查测试的mock对象在测试例程中是否调用了方法,和前边的两个断言不一样,前边的两个只是检查最近一次的调用;看下边的例子(mock的构造仍和上边的例子一样);

    4.assert_has_calls()检查是否按照正确的顺序和正确的参数进行调用的;所以,我们需要给出一个方法的调用顺序,assert的时候按照这个顺序进行检查。

    注明:第一次assert失败是因为参数给错了哎。

    还有,仔细看你会看到,fooCall中的每个元素前边都有call来修饰,这个就是表明,call后边的是一个方法,不加call是不可以的,解释器是不知道fun1是一个方法的,为了使用call这个关键字,我们就需要引入这个模块:from mock import Mock,call。

    三、mock的管理方法:

    1.attach_mock():将一个mock对象添加到另一个mock对象中;

    上述例子中,我们是将mockFoo2添加到mockFoo1中,并重新命名为mock_att。或许,看到这里,你会很好奇,为什么mockFoo1._value1取到的不是100,而是一些id信息呢?因为,哈哈哈,spec只是设置的是mock对象的属性,也就是说mock对象有这些属性,但是属性的值呢~~就说不定了~

    2.configure_mock():更改mock对象的return_value值。

    举例说明:

    疑问:

    为什么mockFoo.fun1不会显示出来fun1函数的输出或者是fun1的return_value值呢???

    人为原因:sooSpec字典的写法出现错误,应该这么写:

    (value值也必须带上引号,但是最后那个异常就不需要了),这样子纠正之后,print mockFoo.fun1()显示的结果就是100.

    3.mock_add_spec(aSpec, spec_set = False):这个函数就是给mock对象添加一个新的属性(mock对象原来的属性就会被擦除),第二个参数是指属性是可读可写,默认是只读,如果想让其拥有写权限,可以将其设置为true.

    4.reset_mock():将mock对象恢复到测试之前的状态,这里也就是避免了重新构造mock对象带来的开销。这里就不给出举例~

    四、mock的统计:

    1.called:跟踪mock对象所做的任意调用的访问器;

    2.call_count:mock对象被工厂调用的次数:

    此例子接着上述例子;

    3.call_args:获取工厂调用时的参数(最近使用的参数):

    4.call_args_list:获取工厂调用的的所有参数,是个列表;

    5.method_calls:测试一个mock对象都调用了哪些方法,结果是一个list。

    6.mock_calls:显示工厂调用和方法调用,下图所示:

    ---------------------

    作者:peiyao456

    来源:CSDN

    原文:https://blog.csdn.net/peiyao456/article/details/77075173

    转载,原文链接。 https://blog.csdn.net/peiyao456/article/details/77075173

    相关文章

      网友评论

          本文标题:Python中的模块学习之mock模块

          本文链接:https://www.haomeiwen.com/subject/hadvbqtx.html