使用自定义模式定义进行Spring Ldap单元测试

时间:2014-12-17 17:08:40

标签: java spring unit-testing ldap spring-ldap

我正在尝试使用Spring Ldap设置嵌入式ldap进行单元测试。但是我需要为自定义objectClasses / attributes定义使用自定义模式。如何使用Spring Ldap测试(LdapTestUtils?)

进行配置

实际上,如果我运行测试,则说明我的自定义objectClass“myOb”未在模式中定义,并显示以下消息:

org.springframework.ldap.UncategorizedLdapException: Failed to populate LDIF; nested exception is javax.naming.directory.NoSuchAttributeException: [LDAP: error code 16 - NO_SUCH_ATTRIBUTE: failed for     Add Request :
...
: OID for name 'myOb' was not found within the OID registry]; remaining name 'cn=123456, ou=MyUser, o=company.com'

如果我从ldif评论objectClass: myOb,则测试失败并显示空值(未读取属性)。

这是我的测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = LdapConfiguration.class, loader = AnnotationConfigContextLoader.class)
public class LdapTest {

    // Ldap port
    private static final int LDAP_PORT = 18880;

    // Base DN for test data
    private static final LdapName baseName = LdapUtils.newLdapName("o=company.com");

    @Autowired
    LdapTemplate ldapTemplate;

    @BeforeClass
    public static void setupBeforeClass() {
        LdapTestUtils.startEmbeddedServer(LDAP_PORT, baseName.toString(), "ldaptest");
        // How to load schema definition ?
    }

    @AfterClass
    public static void teardownAfterClass() throws Exception {
        LdapTestUtils.shutdownEmbeddedServer();
    }

    @Before
    public void setup() throws Exception {
        LdapTestUtils.cleanAndSetup(ldapTemplate.getContextSource(), baseName, new ClassPathResource("ldap/test-users.ldif"));
    }


    @Test
    public void testSearchLdap() throws Exception {     
        String myObId = ldapTemplate.lookup(LdapNameBuilder.newInstance("ou=MyUser, o=company.com").add("cn", "123456").build(), new AbstractContextMapper<String>() {
            @Override
            protected String doMapFromContext(DirContextOperations ctx) {
                return ctx.getStringAttribute("myObId"); // custom type
            }           
        });
        Assert.assertNotNull(myObId); // myObId is null if I comment `objectClass: myOb` !
    }
}

和我的ldif:

dn: ou=MyUser, o=company.com
ou: User
description: MyUser
objectClass: top
objectClass: organizationalunit

dn: cn=123456, ou=MyUser, o=company.com
objectClass: top
objectClass: person
objectClass: myOb
cn: 123456
sn: 823456
myObId: TEST

2 个答案:

答案 0 :(得分:1)

我不知道如何用Spring Ldap做到这一点...... 但我在单元测试中使用Unboundid InMemoryDirectoryServer。服务器的此实现不限制任何自定义objectClasses / attributes定义。 如果你愿意,我可以在这里分享我的JUnitRule。该规则启动InMemory服务器并将ldiff加载到其中

更新:

public class LdapServerRule extends ExternalResource {
private static final Log LOG = LogFactory
        .getLog(LdapServerRule.class);

public static final String DefaultDn = "cn=Directory Manager";
public static final String DefaultPassword = "password";
private String baseDn;
private String dn;
private String password;
private String lDiffPath;
private InMemoryDirectoryServer server;
private int listenPort;

public LdapServerRule(String baseDn, String lDiffPath) {
    this(baseDn, lDiffPath, 0);
}


public LdapServerRule(String baseDn, String lDiffPath, int listenPort) {
    this.lDiffPath = lDiffPath;
    this.baseDn = baseDn;
    this.dn = DefaultDn;
    this.password = DefaultPassword;
    this.listenPort = listenPort;

}

@Override
protected void before() {
    start();
}

@Override
protected void after() {
    stop();
}

public int getRunningPort() {
    return getServer().getListenPort();
}

private void start() {
    InMemoryDirectoryServerConfig config;

    try {
        LOG.info("LDAP server " + toString() + " starting...");
        config = new InMemoryDirectoryServerConfig(getBaseDn());
        config.addAdditionalBindCredentials(getDn(),
                getPassword());
        config.setSchema(null);
        config.setListenerConfigs(
                InMemoryListenerConfig.createLDAPConfig("LDAP", getListenPort()));
        setServer(new InMemoryDirectoryServer(config));

        getServer().importFromLDIF(true, getLDiffPath());
        getServer().startListening();
        LOG.info("LDAP server " + toString() + " started. Listen on port " + getServer().getListenPort());
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

}

private void stop() {
    server.shutDown(true);
    LOG.info("LDAP server " + toString() + " stopped");
}

public String getBaseDn() {
    return baseDn;
}

public String getDn() {
    return dn;
}

public String getPassword() {
    return password;
}

public InMemoryDirectoryServer getServer() {
    return server;
}

public void setServer(InMemoryDirectoryServer server) {
    this.server = server;
}

public String getLDiffPath() {
    return lDiffPath;
}

public int getListenPort() {
    return listenPort;
}

@Override
public String toString() {
    return com.google.common.base.Objects.toStringHelper(this)
            .add("baseDn", baseDn)
            .add("listenPort", listenPort)
            .toString();
}

}

您可以像这样使用此规则

@ClassRule
public static final LdapServerRule LDAP_RULE =
        new LdapServerRule("dc=mmkauth", resourceFilePath("data.ldiff"));

LDAP_RULE.getListenPort()返回连接的实际端口,或者您可以将端口直接传递给构造函数

答案 1 :(得分:1)

Spring Boot提供了两个属性来忽略模式或设置模式文件的路径:

spring.ldap.embedded.validation.enabled=true # Whether to enable LDAP schema validation.
spring.ldap.embedded.validation.schema= # Path to the custom schema.

@See common-application-properties

相关问题