Search code examples
javaspring-bootmockingmockitohttpsession

How to Mock HttpSession and pass it as arguemnt to a method which works with session?


I am using Spring framework 2.4.4 and Intellij Ultimate 2020

I would like to test this method tryGetUser on which I am passing HttpSession, but I can't resolve the problem, because when I am mocking it and setAttribute(); at the //Arrange part of the method it always ends with currentUserUsername to be null.

public User tryGetUser(HttpSession session) {
    String currentUserUsername = (String) session.getAttribute("currentUserUsername");
***// Here this local variable currentUsername is always null;***
    if (currentUserUsername == null) {
        throw new AuthorizationException("No logged in user.");
    }

    try {
        return userService.getByUsername(currentUserUsername);
    } catch (EntityNotFoundException e) {
        throw new AuthorizationException("No logged in user.");
    }
}

Here you can see how I am trying to Mock it, but actually, the session is remaining empty or I don't know, but when the service method starts to execute the attribute is not there.

@ExtendWith(MockitoExtension.class)
public class LoginServiceMvcTests {

    @Mock
    UserRepository mockUserRepository;

    @Mock
    UserService mockUserService;

    @InjectMocks
    MockHttpSession mockHttpSession;

    @InjectMocks
    LoginServiceMvc userService;

    private User junkie;
    private User organizer;

    @BeforeEach
    public void setup() {
        junkie = Helpers.createJunkie();
        organizer = Helpers.createOrganizer();
    }

    @Test
    public void tryGetUser_Should_GetUserFromSession_When_UserIsLogged() {

        // Arrange
        mockHttpSession.setAttribute("luboslav", junkie);
        Mockito.when(mockUserService.getByUsername("luboslav"))
                .thenReturn(junkie);

        // Act
        userService.tryGetUser(mockHttpSession);

        // Assert
        Mockito.verify(mockUserService, Mockito.times(1))
                .getByUsername("luboslav");
    }
}

Solution

  • From Jon skeet answer Mockito doesn't work that way, so you need to actually mock the call instead of setting attribute

    Mockito.when(mockHttpSession. getAttribute("currentUserUsername"))
                .thenReturn("name");
    

    And also HttpSession should be annotated with @Mock not @InjectMocks

    @Mock
    HttpSession httpSession;