Home > Back-end >  How to mock findByPrincipalName in spring\mockito
How to mock findByPrincipalName in spring\mockito

Time:09-10

I am trying to mock findByPrincipalName as in my test context I do not have redis set up but I am unable to do so, I get the following error:

The method thenReturn(Map<String,capture#2-of ?>) in the type OngoingStubbing<Map<String,capture#2-of ?>> is not applicable for the arguments (Map<String,capture#3-of ? extends Session>)

I do not really understand what this error is telling me, below is how I am attempting to mock the method:

Map<String, ? extends Session> sessions = new HashMap<>();

@MockBean
private FindByIndexNameSessionRepository<?> sessionRepository;

when(this.sessionRepository.findByPrincipalName(VALID_SUB)).thenReturn(sessions);

What do I need to do to be able to mock this method? The class RedisSession is not accessible so I cannot create an instance of this to use.

CodePudding user response:

This is not a problem related to mocking, but simply a generic type mismatch. You defined the repository as FindByIndexNameSessionRepository<?>, while your sessions reference type is Map<String, ? extends Session>, so your repository returns ? (2), while you're trying to return an object containing ? extends Session (3). The numbering in the last sentence marks the bounds (?) accordingly to the log you've provided - bounds defined in different places are treated as different type definitions and do not match (read more here).

What you need to do is: define types for both the repository and the object it should return so that they match. One way of doing that would be simply sticking to the interface (Session) or if you wanted to make it more concrete, you could use a generic type definition on the class level (<T extends Session>) and apply it to the repository and the map.

@MockBean
private FindByIndexNameSessionRepository<Session> sessionRepository;

@Test
void test() {
    Map<String, Session> sessions = new HashMap<>();
    when(sessionRepository.findByPrincipalName(VALID_SUB))
            .thenReturn(sessions);
    ...
}
class TypedIndexNameSessionTest<T extends Session> {

    @MockBean
    private FindByIndexNameSessionRepository<T> sessionRepository;

    @Test
    void emptySessions() {
        Map<String, T> sessions = new HashMap<>();
        when(sessionRepository.findByPrincipalName(VALID_SUB))
                .thenReturn(sessions);
        ...
    }
}

I've tested the code locally and pushed it to my GitHub repository - you can see the full example there (all tests pass).

  • Related