11

我目前正在尝试使用嵌入式 ldap 服务器进行单元测试。

在 Spring Security 中,您可以快速定义一个嵌入式 ldap 服务器,用于使用从指定 ldif 加载的一些示例数据的标记进行测试。

我将使用 Spring Ldap 执行 ldap 操作,并考虑测试我的用户服务对象的常用 CRUD 功能。

但是,有没有一种方法可以确保嵌入式服务器中的条目对于我正在运行的每个测试都处于相同的一致状态(有点像删除所有并重新加载 ldif 条目)?

我想到了以下几点:1)表明该方法弄脏了上下文,并强制重新创建嵌入式 ldap 服务器,这听起来很痛苦,因为它必须为每种方法重新启动服务器 2)在测试组织中创建测试条目,这样我就可以取消绑定它们并简单地再次加载 ldif 文件。

我更喜欢 2,但似乎 Spring LDAP 没有很好的帮手来加载和发送 ldif 文件的内容。

关于如何使用 spring 的嵌入式 ldap 服务器或我提到的两种可能的解决方案执行 ldap 测试的任何建议?

谢谢

4

4 回答 4

4

Spring LDAP 不提供围绕 LDAP 操作的事务控制吗?如果是这样,为什么不使用具有自动回滚功能的 Spring 测试框架呢?

我还知道一个包装 LDAP 存储库的 JDBC-LDAP 桥驱动程序,将其呈现为关系数据库。我已经使用 iBatis 连接到这个(我已经在http://lokibear.blogspot.com上写了这个,请参阅 7 月的文章)。我还没有尝试应用事务控制,但驱动程序的网站提到了忽略事务的能力(这意味着你也不能忽略它们......对吗?)。

就像我说的,我还没有尝试过;但是,如果这提供了围绕 LDAP 的事务,那么您可以再次使用 Spring 测试框架来实现自动回滚。我已经围绕该框架发布了一份速查表 - 请参阅我博客上 9 月份的帖子。

对不起,我可能在这里错过了你的目标;但也许这些建议很有用。祝你好运!

于 2009-09-16T21:59:39.430 回答
4

我可能在这里偏离了轨道,但如果您不测试 LDAP 集成本身,您可以使用 Mock 对象模拟 LDAP 连接,该对象始终返回您期望的值,以便您的其他单元测试可以完成。

如果您正在测试 LDAP 连接,那么您实际上是在进行集成测试。在这种情况下,最好连接到真正的 LDAP 实现。

于 2009-11-21T16:29:50.383 回答
2

您可能知道也可能不知道嵌入式 LDAP 功能不是由 Spring LDAP 本身提供的,而是由Apache Directory Server提供的。不幸的是,Apache DS 中的 LDIF 加载器(无论如何都是由 Spring 连接的)具有非常差的错误处理和报告能力,因此可能不会像您真正想要的那样进行单元测试。如果您真的想每次都从头开始,最好的选择是带头进行 Spring Security LDAP 单元测试并每次都重新初始化 Apache DS,并加载干净的 LDIF 文件。

或者,您可以完全避开 LDIF,并构建自己的单元测试包装器,在单元测试运行之前验证数据的前置条件和后置条件。这将是更多的工作,但最终可能对你更好。

于 2009-12-05T05:36:44.867 回答
1

对我来说很好:

@Inject
private ApplicationContext applicationContext;

@Before
public void reloadLdapDirectory() throws NamingException, IOException{
    ApacheDSContainer apacheDSContainer = (ApacheDSContainer) applicationContext.getBean(BeanIds.EMBEDDED_APACHE_DS);
    LdapTestUtils.clearSubContexts(contextSource, DistinguishedName.EMPTY_PATH);

    ClassPathResource classPathResource = new ClassPathResource("ldap.ldif");

    File tempFile = File.createTempFile("spring_ldap_test", ".ldif");
    try {
        InputStream inputStream = classPathResource.getInputStream();
        IOUtils.copy(inputStream, new FileOutputStream(tempFile));
        LdifFileLoader fileLoader = new LdifFileLoader(apacheDSContainer.getService().getAdminSession(), tempFile.getAbsolutePath());
        fileLoader.execute();
    }
    finally {
        try {
            tempFile.delete();
        }
        catch (Exception e) {
            // Ignore this
        }
    }
}

我问了类似的问题并得到了 Luke Taylor 的回答:Integration tests with spring-security and ldap

于 2012-11-20T16:20:48.740 回答