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).