Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 如何在jUnit中测试会话范围bean的销毁?_Spring_Junit_Session Scope - Fatal编程技术网

Spring 如何在jUnit中测试会话范围bean的销毁?

Spring 如何在jUnit中测试会话范围bean的销毁?,spring,junit,session-scope,Spring,Junit,Session Scope,我有一个会话范围的bean,其中保存了一些用户数据,并希望编写一个单元测试,以确保它保持会话范围。 我想在jUnit中模拟会话的开始和结束,并比较会话范围bean的值 目前,我有以下单元测试(草稿): @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = SessionScopedGenericXmlContextLoader.class, locations = { "classpath:/test-ap

我有一个会话范围的bean,其中保存了一些用户数据,并希望编写一个单元测试,以确保它保持会话范围。 我想在jUnit中模拟会话的开始和结束,并比较会话范围bean的值

目前,我有以下单元测试(草稿):

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = SessionScopedGenericXmlContextLoader.class, 
locations = { "classpath:/test-applicationContext.xml","classpath:/cache-config.xml" })
    public class CachingTest extends AbstractJUnit4SpringContextTests {

  // Session scoping
  protected MockHttpSession session;
  protected MockHttpServletRequest request;
  ApplicationContext ctx;

  CacheManager cacheManager;

  Cache accountSettingsCache;

  @Autowired
  @Qualifier("cachedMethods")
  DummyCacheMethods methods;

  @Autowired
  private SecurityContextHolder contextHolder;

  protected void startRequest() {
    request = new MockHttpServletRequest();
    request.setSession(session);
    RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
  }

  protected void endRequest() {
    ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).requestCompleted();
    RequestContextHolder.resetRequestAttributes();
    request = null;
  }

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

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

  }

  @Before
  public void constructSession() {
    ctx = applicationContext;
    cacheManager = (CacheManager) ctx.getBean("cacheManager");
    accountSettingsCache = cacheManager.getCache("accountSettingsCache");
    startRequest();
    startSession();
  }

  @After
  public void sessionClean() {
    endRequest();
    endSession();
    contextHolder.clearContext();
  }

  @Test
 // @DirtiesContext
  public void checkSession1() {

    final Authentication authentication = new Authentication() {

      public String getName() {
        return "Johny";
      }

      public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {
      }

      public boolean isAuthenticated() {
        return true;
      }

      public Object getPrincipal() {
        final CustomUserDetails pr = new CustomUserDetails();
        pr.setUsername("Johny");
        return pr;
      }

      public Object getDetails() {
        return null;
      }

      public Object getCredentials() {
        return null;
      }

      public Collection<GrantedAuthority> getAuthorities() {
        return null;
      }
    };

    contextHolder.getContext().setAuthentication(authentication);
    assertTrue(methods.getCurrentUserName().equals(accountSettingsCache.get("currentUser").get()));
    assertTrue(methods.getCurrentUserName().equals(((CustomUserDetails) authentication.getPrincipal()).getUsername()));
  }

  @Test
 // @DirtiesContext
  public void testSession2() {
    final Authentication authentication2 = new Authentication() {

      public String getName() {
        return "James";
      }

      public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {

      }

      public boolean isAuthenticated() {
        return true;
      }

      public Object getPrincipal() {
        final CustomUserDetails pr = new CustomUserDetails();
        pr.setUsername("James");
        return pr;
      }

      public Object getDetails() {
        return null;
      }

      public Object getCredentials() {
        return null;
      }

      public Collection<GrantedAuthority> getAuthorities() {
        return null;
      }
    };
    SecurityContextHolder.setContext(contextHolder.getContext());
    SecurityContextHolder.clearContext();
    SecurityContextHolder.getContext().setAuthentication(authentication2);

    assertTrue(methods.getCurrentUserName().equals(accountSettingsCache.get("currentUser").get()));
    assertTrue(methods.getCurrentUserName().equals(((CustomUserDetails) authentication2.getPrincipal()).getUsername()));

  }


  @Test
  public void testWiring() {
    assertTrue("cacheManager is null", cacheManager != null);
    assertTrue("accountSettingsCache is null", accountSettingsCache != null);
  }

}
我使用自定义上下文加载器来注册会话范围

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.test.context.support.GenericXmlContextLoader;
import org.springframework.web.context.request.SessionScope;

public class SessionScopedGenericXmlContextLoader extends GenericXmlContextLoader {
  @Override
  protected void customizeBeanFactory(final DefaultListableBeanFactory beanFactory) {
    beanFactory.registerScope("session", new SessionScope());
    super.customizeBeanFactory(beanFactory);
  }
}
单元测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = SessionScopedGenericXmlContextLoader.class, 
locations = { "classpath:/test-applicationContext.xml","classpath:/cache-config.xml" })
    public class CachingTest extends AbstractJUnit4SpringContextTests {

  // Session scoping
  protected MockHttpSession session;
  protected MockHttpServletRequest request;
  ApplicationContext ctx;

  CacheManager cacheManager;

  Cache accountSettingsCache;

  @Autowired
  @Qualifier("cachedMethods")
  DummyCacheMethods methods;

  @Autowired
  private SecurityContextHolder contextHolder;

  protected void startRequest() {
    request = new MockHttpServletRequest();
    request.setSession(session);
    RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
  }

  protected void endRequest() {
    ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).requestCompleted();
    RequestContextHolder.resetRequestAttributes();
    request = null;
  }

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

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

  }

  @Before
  public void constructSession() {
    ctx = applicationContext;
    cacheManager = (CacheManager) ctx.getBean("cacheManager");
    accountSettingsCache = cacheManager.getCache("accountSettingsCache");
    startRequest();
    startSession();
  }

  @After
  public void sessionClean() {
    endRequest();
    endSession();
    contextHolder.clearContext();
  }

  @Test
 // @DirtiesContext
  public void checkSession1() {

    final Authentication authentication = new Authentication() {

      public String getName() {
        return "Johny";
      }

      public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {
      }

      public boolean isAuthenticated() {
        return true;
      }

      public Object getPrincipal() {
        final CustomUserDetails pr = new CustomUserDetails();
        pr.setUsername("Johny");
        return pr;
      }

      public Object getDetails() {
        return null;
      }

      public Object getCredentials() {
        return null;
      }

      public Collection<GrantedAuthority> getAuthorities() {
        return null;
      }
    };

    contextHolder.getContext().setAuthentication(authentication);
    assertTrue(methods.getCurrentUserName().equals(accountSettingsCache.get("currentUser").get()));
    assertTrue(methods.getCurrentUserName().equals(((CustomUserDetails) authentication.getPrincipal()).getUsername()));
  }

  @Test
 // @DirtiesContext
  public void testSession2() {
    final Authentication authentication2 = new Authentication() {

      public String getName() {
        return "James";
      }

      public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {

      }

      public boolean isAuthenticated() {
        return true;
      }

      public Object getPrincipal() {
        final CustomUserDetails pr = new CustomUserDetails();
        pr.setUsername("James");
        return pr;
      }

      public Object getDetails() {
        return null;
      }

      public Object getCredentials() {
        return null;
      }

      public Collection<GrantedAuthority> getAuthorities() {
        return null;
      }
    };
    SecurityContextHolder.setContext(contextHolder.getContext());
    SecurityContextHolder.clearContext();
    SecurityContextHolder.getContext().setAuthentication(authentication2);

    assertTrue(methods.getCurrentUserName().equals(accountSettingsCache.get("currentUser").get()));
    assertTrue(methods.getCurrentUserName().equals(((CustomUserDetails) authentication2.getPrincipal()).getUsername()));

  }


  @Test
  public void testWiring() {
    assertTrue("cacheManager is null", cacheManager != null);
    assertTrue("accountSettingsCache is null", accountSettingsCache != null);
  }

}
getCurrentUser()只是从SecurityContext返回当前主体

但这不起作用,在这条线上测试不通过:

  assertTrue(methods.getCurrentUserName().equals(((CustomUserDetails) authentication2.getPrincipal()).getUsername()));
由于方法调用被缓存,它仍然返回Johnny而不是James

我的缓存相关bean是:

<bean id="accountSettingsCache" class="org.springframework.cache.concurrent.ConcurrentMapCache" scope="session">
    <constructor-arg>
      <value>accountSettingsCache</value>
    </constructor-arg>
    <aop:scoped-proxy proxy-target-class="false" />
  </bean>

  <bean id="defaultCache" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="defaultCache" />

  <bean id="cacheManager" class="my.package.DynamicCacheManager" scope="session">
    <property name="caches">
      <set>
        <ref bean="accountSettingsCache" />
        <ref bean="defaultCache" />
      </set>
    </property>
    <aop:scoped-proxy />
  </bean>

会计设置
accountSettingsCache是会话作用域,我想启动一个新会话并销毁它

如果我取消对DirtiesContext注释的注释,它确实会通过,但我想这不是我想要的

我错过了什么