How to properly use mock in python with unittest setUp(如何通过 unittest setUp 在 python 中正确使用 mock)
问题描述
在我尝试学习 TDD 的过程中,尝试学习单元测试并在 python 中使用 mock.慢慢掌握它,但不确定我是否正确执行此操作.预先警告:我坚持使用 python 2.4,因为供应商 API 是作为预编译的 2.4 pyc 文件提供的,所以我使用的是 mock 0.8.0 和 unittest(不是 unittest2)
In my attempt to learn TDD, trying to learn unit testing and using mock with python. Slowly getting the hang of it, but unsure if I'm doing this correctly. Forewarned: I'm stucking using python 2.4 because the vendor API's come as pre-compiled 2.4 pyc files, so I'm using mock 0.8.0 and unittest ( not unittest2 )
鉴于 'mymodule.py' 中的示例代码
Given this example code in 'mymodule.py'
import ldap
class MyCustomException(Exception):
pass
class MyClass:
def __init__(self, server, user, passwd):
self.ldap = ldap.initialize(server)
self.user = user
self.passwd = passwd
def connect(self):
try:
self.ldap.simple_bind_s(self.user, self.passwd)
except ldap.INVALID_CREDENTIALS:
# do some stuff
raise MyCustomException
现在在我的测试用例文件test_myclass.py"中,我想模拟 ldap 对象.ldap.initialize 返回 ldap.ldapobject.SimpleLDAPObject,所以我认为这是我必须模拟出来的方法.
Now in my test case file 'test_myclass.py', I want to mock the ldap object out. ldap.initialize returns the ldap.ldapobject.SimpleLDAPObject, so I figured that'd be the method I'd have to mock out.
import unittest
from ldap import INVALID_CREDENTIALS
from mock import patch, MagicMock
from mymodule import MyClass
class LDAPConnTests(unittest.TestCase):
@patch('ldap.initialize')
def setUp(self, mock_obj):
self.ldapserver = MyClass('myserver','myuser','mypass')
self.mocked_inst = mock_obj.return_value
def testRaisesMyCustomException(self):
self.mocked_inst.simple_bind_s = MagicMock()
# set our side effect to the ldap exception to raise
self.mocked_inst.simple_bind_s.side_effect = INVALID_CREDENTIALS
self.assertRaises(mymodule.MyCustomException, self.ldapserver.connect)
def testMyNextTestCase(self):
# blah blah
让我想到几个问题:
- 看起来对吗?:)
- 这是尝试模拟在我正在测试的类中实例化的对象的正确方法吗?
- 是否可以在 setUp 上调用 @patch 装饰器,否则会导致奇怪的副作用?
- 有没有办法模拟引发 ldap.INVALID_CREDENTIALS 异常而不必将异常导入我的测试用例文件?
- 我应该改用 patch.object() 吗?如果可以,该怎么做?
谢谢.
推荐答案
你可以使用patch()
作为类装饰器,而不仅仅是作为函数装饰器.然后你可以像以前一样传入模拟函数:
You can use patch()
as a class decorator, not just as a function decorator. You can then pass in the mocked function as before:
@patch('mymodule.SomeClass')
class MyTest(TestCase):
def test_one(self, MockSomeClass):
self.assertIs(mymodule.SomeClass, MockSomeClass)
参见:对每个测试方法应用相同的补丁(其中还列出了替代方法)
See: Applying the same patch to every test method (which also lists alternatives)
如果您希望对所有测试方法进行修补,那么在 setUp 上以这种方式设置修补程序更有意义.
It makes more sense to set up the patcher this way on setUp if you want the patching to be done for all the test methods.
这篇关于如何通过 unittest setUp 在 python 中正确使用 mock的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何通过 unittest setUp 在 python 中正确使用 mock
基础教程推荐
- 何时使用 os.name、sys.platform 或 platform.system? 2022-01-01
- 如何让 python 脚本监听来自另一个脚本的输入 2022-01-01
- Python kivy 入口点 inflateRest2 无法定位 libpng16-16.dll 2022-01-01
- 在 Python 中,如果我在一个“with"中返回.块,文件还会关闭吗? 2022-01-01
- 使用PyInstaller后在Windows中打开可执行文件时出错 2022-01-01
- 线程时出现 msgbox 错误,GUI 块 2022-01-01
- 筛选NumPy数组 2022-01-01
- 用于分类数据的跳跃记号标签 2022-01-01
- Dask.array.套用_沿_轴:由于额外的元素([1]),使用dask.array的每一行作为另一个函数的输入失败 2022-01-01
- 如何在海运重新绘制中自定义标题和y标签 2022-01-01