开发神技能 | Python Mock 的入门

  • 时间:
  • 浏览:0

from client import visit_ustack

Mock是哪此

client.send_request = mock.Mock()

def visit_ustack():

def send_request(url):

一点的参数请参考官方文档。

· side_effect: 你这个 参数指向有有另四个 可调用对象,一般本来 函数。当mock对象被调用时,还会 该函数返回值还会DEFAULT时,那么以该函数的返回值作为mock对象调用的返回值。

上边你这个 本来 使用mock对象的基本步骤了。在上边的例子中让我们歌词 歌词 都都替换了本人写的模块的对象,我觉得 也还并能替换标准库和第三方模块的对象,最好的办法是一样的:先import进来,还会 替换掉指定的对象就还并能了。

status_code = '404'

patch.object和patch的效果是一样的,只不过用法不得劲不同。举例来说,同样是上边你这个 例子,换成patch.object一句话是本来 的:

class TestClient(unittest.TestCase):

from client import visit_ustack

稍微高级点的用法

Mock对象的一般用法是本来 的:

def test_success_request(self):

官方文档

· https://docs.python.org/3.4/library/unittest.mock-examples.html

mock还未加入标准库。

当访问有有另四个 mock对象中不存在的属性时,mock会自动建立有有另四个 子mock对象,还会 把正在访问的属性指向它,你这个 功能对于实现多级属性的mock很方便。

def test_call_send_request_with_right_arguments(self):

self.assertEqual(client.visit_ustack(), '404')

import unittest

client.send_request = fail_send

fail_send = mock.Mock(return_value='404')

从上边的例子中还还并能看完,指定mock对象的return_value还还并能使用属性赋值的最好的办法。

def test_success_request(self):

client.v2_client.get.return_value = '80'

Mock的安装和导入

patch和patch.object

class Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, **kwargs)

· name: 你这个 是用来命名有有另四个 mock对象,本来 起到标识作用,当你print有有另四个 mock对象的就让,还并能看完它的name。

Mock对象的call_args表示该mock对象被调用的tuple,tuple的每个成员还会有有另四个 mock.call对象。mock.call你这个 对象代表了一次对mock对象的调用,其内容是有有另四个 tuple,所含高高另四个 元素,第有有另四个 元素是调用mock对象时的位置参数(args),第四个元素是调用mock对象时的关键字参数(*kwargs)。

from unittest import mock

现在来分析下上边的用例,让我们歌词 歌词 都只有检查的项目有有有另四个 :

call_args = client.send_request.call_args

Python 2.7

本来 替换掉有有另四个 对象的指定名称的属性,用法和setattr你这个 。

那么怎样才能在那么测试服务器的情况下进行上边你这个 情况的单元测试呢?Mock模块本来 答案。上边还会 说过了,mock模块还并能替换Python对象。让我们歌词 歌词 都都假设a.b.c的代码如下:

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

mock对象的自动创建

mock对象有一点最好的办法还并能用来检查该对象是是是否是是被调用过、被调用时的参数怎样才能、被调用了多少等。实现哪此功能还并能调用mock对象的最好的办法,具体的还并能查看mock的文档。这里让我们歌词 歌词 都都举个例子。

resp = requests.get(url)

class TestClient(unittest.TestCase):

r = requests.get(url)

import mock

内部模块调用visit_ustack()来访问UnitedStack的官网。下面让我们歌词 歌词 都都使用mock对象在单元测试中分别测试访问正常和访问不正常的情况。

你肯定很奇怪,本文不本来 教人使用mock的么?我觉得 还会的,我发现本人在学习mock的过程中遇到的主要困难是不清楚mock能做哪此,而还会mock对象到底有哪此函数。还会 写这篇文章的主要目的是为了说明mock能做哪此。

对最好的办法调用进行检查

你这个 就让,你就得到了有有另四个 mock过的client实例,调用该实例的v2_client.get()最好的办法会得到的返回值是”80″。

import requests

client = mock.Mock()

还是使用上边的代码,这次让我们歌词 歌词 都只有检查visit_ustack()函数调用send_request()函数时,传递的参数类型是是是否是是正确。让我们歌词 歌词 都都还并能像下面本来 使用mock对象。

from client import visit_ustack

class TestClient(unittest.TestCase):

def test_fail_request(self):

你这个 测试类和让我们歌词 歌词 都都刚才写的第有有另四个 测试类一样,包所含高另四个 测试,只不过这次还会显示创建有有另四个 mock对象还会 进行替换,本来 使用了patch函数(作为上下文管理器使用)。

self.assertEqual(visit_ustack(), status_code)

举个例子来说:让我们歌词 歌词 都都有有另四个 多简单的客户端实现,用来访问有有另四个 URL,当访问正常时,只有返回情况码80,不正常时,只有返回情况码404。首先,让我们歌词 歌词 都都的客户端代码实现如下:

怎样才能学习使用mock?

import mock

$ sudo pip install mock

client.send_request = success_send

Python 3.4

mock还会 加入了标准库。

Mock对象的called属性表示该mock对象是是是否是是被调用过。

还会 利用mock模块,那么就还并能达到本来 的效果:使用有有另四个 mock对象替换掉上边的requests.get函数,还会 执行函数c时,c调用requests.get的返回值就并能由让我们歌词 歌词 都都的mock对象来决定,而不只有服务器的参与。简单的说,本来 让我们歌词 歌词 都都用有有另四个 mock对象替换掉c函数和服务器交互的过程。你一定很好奇你这个 功能是怎样才能实现的,你这个 是mock模块内部的实现机制,都那么本文的讨论范围。本文主要讨论怎样才能用mock模块来除理上边提到的你这个 单元测试场景。

上边讲的是mock对象最基本的用法。下面来看看mock对象的稍微高级点的用法(并还会很高级啊,最删改最高级的直接去看mock的文档即可,上边给出)。

class Mock的参数

基本用法

self.assertEqual(client.visit_ustack(), '80')

fail_send = mock.Mock(return_value=status_code)

with mock.patch.object(client, 'send_request', fail_send):

with mock.patch('client.send_request', fail_send):

在Python 3.3就让的版本中,只有另外安装mock模块,还并能使用pip命令来安装:

def test_fail_request(self):

来自:diabloneo

def c(url):

先来看看Mock你这个 类的参数,在上边看完的类定义中,让我们歌词 歌词 都都知道它有好多少参数,这里介绍最主要的多少:

status_code = '404'

def test_fail_request(self):

· return_value: 你这个 让我们歌词 歌词 都都刚才使用过了,你这个 字段还并能指定有有另四个 值(还会 对象),当mock对象被调用时,还会 side_effect函数返回的是DEFAULT,则对mock对象的调用会返回return_value指定的值。

· http://www.voidspace.org.uk/python/mock/index.html

success_send = mock.Mock(return_value=status_code)

import client

在了解了mock对象就让,让我们歌词 歌词 都都来看有有另四个 方便测试的函数:patch和patch.object。这有有另四个 函数还会返回有有另四个 mock内部的类实例,你这个 类是class _patch。返回的你这个 类实例既还并能作为函数的装饰器,也还并能作为类的装饰器,也还并能作为上下文管理器。使用patch还会 patch.object的目的是为了控制mock的范围,意思本来 在有有另四个 函数范围内,还会 有有另四个 类的范围内,还会 with一句话的范围内mock掉有有另四个 对象。让我们歌词 歌词 都都看个代码例子即可:

return r.status_code

with mock.patch('client.send_request', success_send):

status_code = '80'

Mock对象是mock模块中最重要的概念。Mock对象本来 mock模块中的有有另四个 类的实例,你这个 类的实例还并能用来替换一点的Python对象,来达到模拟的效果。Mock类的定义如下:

Mock你这个 词在英语所含模拟的你这个 意思,还会 让我们歌词 歌词 都都还并能猜测出你这个 库的主要功能是模拟一点东西。准确的说,Mock是Python所含高另四个 用于支持单元测试的库,它的主要功能是使用mock对象替代掉指定的Python对象,以达到模拟对象的行为。简单的说,mock库用于如下的场景:

这里给出你这个 定义本来 要说明下Mock对象我觉得 本来 个Python类而已,当然,它内部的实现是很巧妙的,有兴趣的还并能去看mock模块的代码。

还会 在代码中就还并能直接import进来:

当你知道了mock能做哪此就让,怎样才能才能学习并掌握mock呢?最好的办法本来 查看阅读官方文档,并在本人的单元测试中使用。

https://segmentfault.com/a/1190000002.jpg"max-width: 80%;min-height: 1em;color: rgb(62, 62, 62);font-size: 16px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 25.6px;text-align: center;box-sizing: border-box !important;word-wrap: break-word !important;">

success_send = mock.Mock(return_value='80')

假设你开发的项目叫a,上边所含了有有另四个 模块b,模块b中的有有另四个 函数c(也本来 a.b.c)在工作的就让只有调用发送请求给特定的服务器来得到有有另四个 JSON返回值,还会 根据你这个 返回值来做除理。还会 要为a.b.c函数写有有另四个 单元测试,该怎样才能做?

self.assertEqual(visit_ustack(), status_code)

从Python 3.3刚开始了了,mock模块还会 被合并到标准库中,被命为unittest.mock,还并能直接import进来使用:

client.visit_ustack()

· https://docs.python.org/3.4/library/unittest.mock.html

self.assertIsInstance(call_args0, str)

fail_send = mock.Mock(return_value=status_code)

self.assertEqual(visit_ustack(), status_code)

有有另四个 简单的最好的办法是搭建有有另四个 测试的服务器,在单元测试的就让,让a.b.c函数和你这个 测试服务器交互。还会 你这个 做法有有有另四个 大大问题 :

import requests

最后,学习mock技能你应该要并能感受到两种控制的快感,就那个她 能享受控制内部服务的快乐。当你感受到你这个 快感的就让,你的mock应该就达到熟练使用的水平了。

self.assertEqual(client.send_request.called, True)

Mock对象