在unittests中用于伪造ldap服务器的ldapobject的实现。
fakeldap的Python项目详细描述
此模块的目标是提供模拟LDAP后端服务器的简单方法 为了你的单元测试。它可以预先定义一组目录 可以查询的条目或设置LDAP查询的固定返回值。它起作用 作为python ldap的LDAPObject类的替换 模块。它实现了该类允许的方法的子集。
此模块实现了MockLDAP类,该类同时作为 LDAPObject以及LDAP模块。大部分代码和设计 摘自Peter Sagerson的优秀django-auth-ldap模块。
安装
获取并安装代码:
$ git clone git://github.com/30loops/fakeldap.git $ cd fakeldap $ python setup.py install
如果需要,可以运行测试:
$ python setup.py nosetests
用法
注意
这段代码仍然是实验性的,到目前为止还没有得到很好的测试。所以 文档
MockLDAP类替换python ldap模块的LDAPObject。 最简单的方法是覆盖ldap.initialize以返回 MockLDAP而不是LDAPObject。下面的例子使用michael foord的 Mock实现这一目标的库:
import unittest from mock import patch from fakeldap import MockLDAP _mock_ldap = MockLDAP() class YourTestCase(unittest.TestCase): def setUp(self): # Patch where the ldap library is used: self.ldap_patcher = patch('app.module.ldap.initialize') self.mock_ldap = self.ldap_patcher.start() self.mock_ldap.return_value = _mock_ldap def tearDown(self): _mock_ldap.reset() self.mock_ldap.stop()
模拟LDAP对象实现以下LDAP操作:
- 简单绑定
- 搜索
- 比较s
- 修改s
- 删除s
- 添加s
- 重命名s
这是一个如何将MockLDAP与固定返回值一起使用的示例:
def test_some_ldap_group_stuff(self): # Define the expected return value for the ldap operation return_value = ("cn=testgroup,ou=group,dc=30loops,dc=net", { 'objectClass': ['posixGroup'], 'cn': 'testgroup', 'gidNumber': '2030', }) # Register a return value with the MockLDAP object _mock_ldap.set_return_value('add_s', ("cn=testgroup,ou=groups,dc=30loops,dc=net", ( ('objectClass', ('posixGroup')), ('cn', 'testgroup'), ('gidNumber', '2030'))), (105,[], 10, [])) # Run your actual code, this is just an example group_manager = GroupManager() result = group_manager.add("testgroup") # assert that the return value of your method and of the MockLDAP # are as expected, here using python-nose's eq() test tool: eq_(return_value, result) # Each actual ldap call your software makes gets recorded. You could # prepare a list of calls that you expect to be issued and compare it: called_records = [] called_records.append(('simple_bind_s', {'who': 'cn=admin,dc=30loops,dc=net', 'cred': 'ldaptest'})) called_records.append(('add_s', { 'dn': 'cn=testgroup,ou=groups,dc=30loops,dc=net", 'record': [ ('objectClass', ['posixGroup']), ('gidNumber', '2030'), ('cn', 'testgroup'), ]})) # And again test the expected behaviour eq_(called_records, _mock_ldap.ldap_methods_called_with_arguments())
除了固定特定调用的返回值外,还可以模拟一个完整的调用 具有条目目录的LDAP服务器:
# Create an instance of MockLDAP with a preset directory tree = { "cn=admin,dc=30loops,dc=net": { "userPassword": "ldaptest" } } mock_ldap = MockLDAP(tree) record = [ ('uid', 'crito'), ('userPassword', 'secret'), ] # The return value I expect when I add another record to the directory eq_( (105,[],1,[]), mock_ldap.add_s("uid=crito,ou=people,dc=30loops,dc=net", record) ) # The expected directory directory = { "cn=admin,dc=30loops,dc=net": {"userPassword": "ldaptest"}, "uid=crito,ou=people,dc=30loops,dc=net": { "uid": "crito", "userPassword": "secret"} } # Compare the expected directory with the MockLDAP directory eq_(directory, mock_ldap.directory)