如何模拟 HttpSession 并将其作为参数传递给与会话一起使用的方法?

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

我正在使用 Spring 框架 2.4.4 和 Intellij Ultimate 2020

我想测试我正在传递 HttpSession 的方法 tryGetUser,但我无法解决问题,因为当我在 [=14] 处模拟它并且 setAttribute(); =] 总是以 currentUserUsername 结尾的方法的一部分为空。

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.");
    }
}

在这里你可以看到我是如何尝试模拟它的,但实际上,会话保持为空或者我不知道,但是当服务方法开始执行时属性不存在。

@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");
    }
}

From answer Mockito 不能那样工作,所以你需要实际模拟调用而不是设置属性

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

而且 HttpSession 应该用 @Mock 注释而不是 @InjectMocks

@Mock
HttpSession httpSession;

使用 MockHttpSession,这是一个实际的真实对象(不仅仅是 Mockito 接口模拟),专门用于此类测试。它基本上是一个 empty/blank 容器,因此您不必模拟所有标准行为,只需用您想要的任何属性填充它即可。