Spring embedded ldap server in unit tests

16,548

Solution 1

I may be off-track here, but if you're not testing the LDAP integration itself, you could Mock out the LDAP connection with a Mock object that always returns the values you expect so that your other Unit Tests can complete.

If you're testing the LDAP connection then you're really doing an integration test. In which case it's probably best to connect to a real LDAP implementation.

Solution 2

You may or may not know that the embedded LDAP functionality is not provided by Spring LDAP itself, but Apache Directory Server. Unfortunately, the LDIF loader in Apache DS (as wired by Spring, anyway) has very poor error handling and reporting capability, and as such is probably not going to behave as you really want for a unit test. Your best bet if you really want to start from a clean slate each time is to take the lead of the Spring Security LDAP unit tests and reinitialize Apache DS every time, with a clean LDIF file load.

Alternatively, you could eschew LDIF altogether and construct your own unit test wrapper that verifies the pre- and post-conditions of the data prior to your unit tests running. This would be more work, but ultimately may work out better for you.

Solution 3

Works fine for me:

@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
        }
    }
}

I asked something similar and got an answer from Luke Taylor: Integration tests with spring-security and ldap

Share:
16,548

Related videos on Youtube

Kent Lai
Author by

Kent Lai

Updated on April 21, 2022

Comments

  • Kent Lai
    Kent Lai about 2 years

    I am currently trying to use an embedded ldap server for unit tests.

    In Spring Security, you can quickly define an embedded ldap server for testing with the tag with some sample data loaded from the specified ldif.

    I will be using Spring Ldap to perform ldap operations, and thinking of testing the usual CRUD features of my User service object.

    Is there, however, a way to ensure that the entries in the embedded server to be in the same consistent state (sort of like a delete all and reload the ldif entries) for each test I am running?

    I thought of the following: 1) Indicate that the method dirties the context, and force a recreation of the embedded ldap server, which sounds painful as it would have to restart the server for every method 2) Create the test entries in a test organization, such that I can unbind them and simply load in the ldif file again there.

    I prefer 2, but it seems like the Spring LDAP has no good helpers to load and send across the content of a ldif file.

    Any suggestions on how you perform ldap testing with an embedded ldap server of spring, or of the two possible solutions I mention?

    Thanks