How to Mock LdapTemplate in Java and get full code coverage

Tags: , , , ,



I am trying to get full coverage on a very simple junit test using Mockito and am striking out. My disclaimer is that I am new to Mockito though what I am trying to do would seem pretty straightforward.

Note that my junit test passes, it is just that the coverage is not complete. When the test is run, the part of the method that returns true (users list is not empty) is not getting run/covered.

My questions are…

  1. Does ldap need to get primed with any test data?

  2. Can you simply mock ldap data?

Any insight you can offer is greatly appreciated.

Here is the method (class name = LdapRepository) being tested…

public Mono<Boolean> ldapTemplateQuery(Email email) {

        Mono<Boolean> blockingWrapper = Mono.fromCallable(() -> {
            List<LdapUser> users = ldapTemplate.find(query().where("cn").is(email.address()), LdapUser.class);
            if (users.isEmpty()) {
                return false;
            } else {
                return true;
            }
        }).onErrorResume(
                original -> Mono.error(new UserNotFoundException("User not found for email " + email.address())));
        return blockingWrapper.subscribeOn(Schedulers.elastic());
    } 

And here is the junit class…

@RunWith(MockitoJUnitRunner.class)
public class LdapUserRepositoryMockTest {

    private @InjectMocks LdapUserRepository ldapUserRepository;

    @Mock
    private LdapTemplate ldapTemplate;

    Email email = new Email("abcd@xyz.com");
    User user = new User(email);

    static final String password = "VGVzdEAxMjM=";
    
    @Test
    public void ldapTemplateQueryTest() {

        LdapUser ldapUser = new LdapUser(user, password.toCharArray());
        List<LdapUser> users = new ArrayList<>();
        users.add(ldapUser);

        lenient().when(ldapTemplate.find(query().where(Mockito.anyString()).is(Mockito.anyString()), LdapUser.class)).thenReturn(users);
        
        Mono<Boolean> locked = ldapUserRepository.ldapTemplateQuery(email);
        StepVerifier.create(locked).expectNext(false).verifyComplete();
    }

And here is the screenshot of the coverage results…

enter image description here

Answer

With much help from someone, I was able to get my answer. As you will see below, it was a rather minor change to the lenient statement.

Hopefully this will be a help to someone along the way.

@RunWith(MockitoJUnitRunner.class)
public class LdapUserRepositoryMockTest {

    private @InjectMocks LdapUserRepository ldapUserRepository;

    @Mock
    private LdapTemplate ldapTemplateMock;

    Email email = new Email("abcd@xyz.com");
    User user = new User(email);

    static final String PASSWORD = "VGVzdEAxMjM=";

    @Test
    public void ldapTemplateQueryTest() {

        LdapUser ldapUser = new LdapUser(user, PASSWORD.toCharArray());
        List<LdapUser> users = new ArrayList<>();
        users.add(ldapUser);
 
        lenient()
                .when(ldapTemplateMock.find(Mockito.any(), Mockito.eq(LdapUser.class)))
                .thenReturn(users);

        Mono<Boolean> locked = ldapUserRepository.checkIfAccountLocked(email);
        StepVerifier.create(locked).expectNext(true).verifyComplete();
    }
}


Source: stackoverflow