首先,我真的很想了解为什么我应该使用模拟(Python Mock 库)。
为了测试某些东西而快速制作一个小对象和使用模拟对象有什么区别?
与其他方法相比,模拟有哪些优势(我真的需要一些“现场”示例来理解这个方法)?在某些情况下模拟是必不可少的吗?
另外:mock 对象和 magicmock 对象有什么区别?他们如何连接?
第二件事是模拟什么/在哪里。
例如,我应该只模拟数据库查询结果吗? 我的意思是:模拟数据是否应该始终是远程数据?
tl;dr:请向从未在任何语言中使用过模拟的人解释 Python 中的模拟概念。
最佳答案
模拟对象旨在快速轻松地表示一些复杂的对象,而无需在测试期间手动为该对象设置 stub 。它只是一个有用的实用程序,可以让编写测试变得更容易一些。
至于模拟什么/在哪里模拟,任何在被测模块之外的东西都应该被模拟。您要测试的只是当前模块代码,而不是被测模块正在调用的某个模块的代码。
一个简单的例子是一些使用 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 只是为特定测试注入(inject)和删除模拟的好方法。 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'})
关于Python mocking-理解概念和必要性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19918700/