java 如何在 Spring Junit 中创建会话

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27102878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 11:13:28  来源:igfitidea点击:

How to create session in Spring Junit

javaspringunit-testingjunitspring-test

提问by grep

I have such layers:

我有这样的层:

Spring Controller -> Services layer -> Dao Layer (JPA).

Spring Controller -> 服务层 -> Dao 层(JPA)。

I want to write test cases of services and controller. In the other Junit will invoke controller, controller will invoke services, service layer gets database information and etc..

我想编写服务和控制器的测试用例。在另一个Junit中会调用控制器,控制器会调用服务,服务层获取数据库信息等等。

In this case I do not want mocking, I want just to write junit test case (I must invoke service and service must get real data from database).

在这种情况下,我不想模拟,我只想编写 junit 测试用例(我必须调用服务并且服务必须从数据库中获取真实数据)。

I have only one problem, service layer get's user id from session. I get session with autowired annotation. How can I create fake session during test cases?

我只有一个问题,服务层从会话中获取用户 ID。我得到了带有自动装配注释的会话。如何在测试用例期间创建假会话?

p.s I think mock is not for me... because I do not wont to mock my service, I want to create real invoke of controller with real db data...

ps 我认为 mock 不适合我......因为我不会嘲笑我的服务,我想用真实的数据库数据创建真正的控制器调用......

回答by grep

We can do with mock. Here is sample of code.

我们可以用模拟来做。这是代码示例。

private MockMvc mockMvc;

        @Autowired
        private FilterChainProxy springSecurityFilterChain;

        @Autowired
        private WebApplicationContext wac;

        protected MockHttpSession session;

        protected MockHttpServletRequest request;

        @Before
        public void setup() {
            this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).addFilters(this.springSecurityFilterChain).build();
        }

        @Test
        void test(){
        // I log in and then returns session 
        HttpSession session = mockMvc.perform(post("/j_spring_security_check").param("NAME", user).param("PASSWORD", pass))
                    .andDo(print()).andExpect(status().isMovedTemporarily()).andReturn().getRequest().getSession();
        }

Also we can do with this way, you can just to call startSession() method, and there will be "current" session returned.

我们也可以用这种方式,你只需调用 startSession() 方法,就会返回“当前”会话。

protected void startSession() {
        session = new MockHttpSession();
    }

    protected void endSession() {
        session.clearAttributes();
        session = null;
    }

    // we can create request too, just simple way
    protected void startRequest() {
        request = new MockHttpServletRequest();
        request.setSession(session);
        RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
    }

回答by Sam Brannen

One option would be to inject the user ID (not the HttpSession) into your service component using a SpEL expression. To achieve proper run-time behavior, you must make sure your service component is an AOP-scoped proxy.

一种选择是HttpSession使用 SpEL 表达式将用户 ID(而不是)注入到您的服务组件中。为了实现正确的运行时行为,您必须确保您的服务组件是 AOP 范围的代理。

Take a look at the "Testing request and session scoped beans"section of the Spring reference manual for further information.

查看Spring 参考手册的“测试请求和会话作用域 bean”部分以获取更多信息。

Regards,

问候,

Sam (spring-testcomponent lead)

Sam spring-test组件负责人)

回答by Joshua Kaldon

I wrote the following function to create "real" sessions when using a mongo session store.

我编写了以下函数来在使用 mongo 会话存储时创建“真实”会话。

private Session generateMongoHttpSession(final Role role, final Permission... permissions) {
  final Set<GrantedAuthority> authorities =
    role.getPermissions()
        .stream()
        .map(p -> new SimpleGrantedAuthority(p.toString()))
        .collect(Collectors.toSet());

  Arrays.stream(permissions)
    .forEach(p -> authorities.add(new SimpleGrantedAuthority(p.toString())));

  final UserDetails userDetails =
    new org.springframework.security.core.userdetails.User(
        "test-user-name", "test-password", true, true, true, true, authorities);

  final Authentication authentication =
    new UsernamePasswordAuthenticationToken(
        userDetails, userDetails.getPassword(), userDetails.getAuthorities());

  final UsernamePasswordAuthenticationToken authenticationToken =
    new UsernamePasswordAuthenticationToken(
          userDetails, authentication.getCredentials(), userDetails.getAuthorities());
  authenticationToken.setDetails(authentication.getDetails());

  final SecurityContextImpl context = new SecurityContextImpl();
  context.setAuthentication(authentication);

  final MongoExpiringSession session = mongoOperationsSessionRepository.createSession();
  session.setAttribute("SPRING_SECURITY_CONTEXT", context);
  session.setAttribute("sessionId", session.getId());
  mongoOperationsSessionRepository.save(session);

  return session;
}