单元测试-----Mock

Mock

Mock是Python中一个用于支持测试的库,主要功能是使用mock对象代替掉指定的Python对象,以达到模拟对象的行为。

Mock对象
基本用法

Mock对象是mock模块中的一个类的实例,这个类的实例可以用来替换其他的Python对象,来达到模拟的效果。Mock类的定义如下:
class Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, **kwargs)
这里给出这个定义只是说明下Mock对象其实就是Python类而已,它内部的实现是很巧妙的。
Mock对象的一般用法是这样的:
1.找到要替换的对象,这个对象可以是一个类,或者是一个函数,或者是一个类实例。
2. 然后实例化Mock类得到一个mock对象,并且设置这个mock对象的行为,比如调用的时候返回什么值,被访问成员的时候返回什么值等。
3. 使用这个mock对象替换掉我们想要替换的对象,就是1中确定的对象。
4.之后就可以开始写测试代码,这个时候我们可以保证我们替换掉的对象在测试用例执行的过程中行为和我们预设的一样。

举个例子来说:我们有一个简单的客户端实现,用来访问一个URL,当访问正常时,需要返回状态码200,不正常时,需要返回状态码404。首先,我们的客户端代码实现如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests


def send_request(url):
    r = requests.get(url)
    return r.status_code


def visit_ustack():
    return send_request('http://www.ustack.com')

使用mock对象在单元测试中分别测试访问正常和访问不正常的情况。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import unittest

import mock

import client


class TestClient(unittest.TestCase):

    def test_success_request(self):
        success_send = mock.Mock(return_value='200')
        client.send_request = success_send
        self.assertEqual(client.visit_ustack(), '200')

    def test_fail_request(self):
        fail_send = mock.Mock(return_value='404')
        client.send_request = fail_send
        self.assertEqual(client.visit_ustack(), '404')

1.找到要替换的对象: 我们需要测试的是visit_ustack这个函数,那么我们需要替换掉send_request这个函数
2.实例化Mock类得到一个mock对象,并且设置这个mock对象的行为,在成功测试中,我们设置mock对象的返回值为字符串“200”,在失败测试中,我们设置mock对象的返回值为字符串“404”。
3.使用这个mock对象替换掉我们想替换的对象,我们替换掉了client.send_request
4. 写测试代码。我们调用client.visit_ustack(),并且期望它的返回值和我们预设的一样。

class Mock的参数

mock这个类的参数:
(1) name: 这个是来命名一个mock对象,只是起到标识作用,当你print一个mock对象的时候,可以看到它的name。
(2)return_value:这个字段指定一个值(或对象),当mock对象被调用时,如果side_effect函数返回的是DEFAULT,则对mock对象的调用会返回return_value指定的值。
(3)side_effect:这个参数指向一个可调用对象,一般就是函数。当mock对象被调用时,如果该函数返回值不是DEFAULT时,那么以该函数的返回值作为mock对象调用的返回值。

mock对象的自动创建

当访问一个mock对象中不存在的属性时,mock会自动建一个mock对象,并且把正在访问的属性指向它,这个功能对于实现多级属性的mock很方便。

cient = Client()
client.V2_client.get.return_value = ‘200’
这个时候。得到了一个mock过的client实例,调用该实例的v2_client.get()方法会得到的返回值是“200”。
从上面的例子中还可以看到,指定mock对象的return_value还可以使用属性赋值的方法。

对方法调用进行检查

mock对象有一些方法可以用来检查该对象是否被调用过、被调用时的参数如何、被调用了几次等,实现这些功能可以调用mock对象的方法,具体的可以查看mock的文档。
还是使用上面的代码,这次我们要检查visit_ustack()函数调用send_request()函数时,传递的参数类型是否正确。我们可以像下面这样使用mock对象。

class TestClient(unittest.TestCase):
	
	def test_call_send_request_with_right_arguments(self):
		client.send_request = mock.Mock()
		client.visit_ustack()
		self.asserEqual(client.send_request.called,True)
		call_args =client.send_request.call_args
		self.assertIsInstance(call_args[0][0],str)

Mock对象的called属性表示该mock对象是否被调用过。
Mock对象的调用,其内容是一个tuple,tuple的每一个成员都是一个mock.call对象。mock.all这个对象代表了一次对mock对象的调用,其内容是一个tuple,含两个元素,第一个元素是调用mock对象时位置参数(*args),第二个元素是调用mock对象时关键字参数(**kwargs)。
上面的用例,检查的项目有两个:

  1. visit_ustack()调用了send_request()
    2.调用的参数是一个字符串
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值