在我尝试学习 TDD 时,尝试学习单元测试并在 python 中使用 mock。慢慢掌握它,但不确定我是否正确执行此操作。预先警告:我坚持使用 python 2.4,因为供应商 API 是作为预编译的 2.4 pyc 文件提供的,所以我使用的是 mock 0.8.0 和 unittest (不是 unittest2 )
鉴于“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,所以我认为这是我必须模拟的方法。
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() 吗?如果是,怎么做?
谢谢。