Python嘲笑 - 理解概念和必要性

时间:2013-11-12 00:25:46

标签: python unit-testing testing mocking

首先,我真的想了解为什么我应该使用mocking(Python Mock库)。

快速制作一个小对象以满足测试需求和使用模拟对象之间的区别是什么?

模拟比其他方法有什么好处(我真的需要一些“实时”的例子来理解这个)?在某些情况下嘲笑是否必不可少?

另外:模拟对象和magicmock对象之间有什么区别?他们如何联系?

第二件事是什么/什么要模拟。

我应该只模拟数据库查询结果吗? 我的意思是:模拟数据应该始终是远程数据吗?

tl;博士:请将Python中的模拟概念解释为从未在任何语言中使用它的人。

1 个答案:

答案 0 :(得分:2)

模拟对象旨在快速轻松地表示一些复杂对象,而无需在测试期间手动浏览并设置该对象的存根。它只是一个有用的实用程序,可以使编写测试更容易。

关于模拟的内容/位置,应该模拟测试模块外部的任何内容。您要测试的只是当前的模块代码,而不是被测模块调用的某些模块的代码。

一个简单的例子是一些使用simplejson模块的代码。

import simplejson

def my_fn(args):
  return simplejson.dumps({'args': args})

你要测试的只是函数my_fn正确调用simplejson.dumps(),所以你模拟了simplejson。您并不关心传递给simplejson的对象是否正确转换为json作为simplejson模块范围内的测试(如果您愿意,可以运行它自己的测试集)。

import working_code
import mock

@mock.patch('working_code.simplejson')
def test_my_fn(mock_simplejson):
    working_code.my_fn('test-args')
    mock_simplejson.dumps.assert_called_with({'args': 'test-args'})

请注意,mock.patch只是为特定测试注入和删除模拟的一种很好的方法。运行test_my_fn后,working_code.simplejson返回到调用函数之前的状态。如果这令人困惑,您可以将测试示例视为:

import working_code
import mock

def test_my_fn():
    mock_simplejson = mock.Mock()
    working_code.simplejson = mock_simplejson
    working_code.my_fn('test-args')
    mock_simplejson.dumps.assert_called_with({'args': 'test-args'})