如何在jUnit中测试会话范围bean的破坏?

时间:2012-03-27 19:56:38

标签: spring junit session-scope

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

现在我有以下(粗略草案)的单元测试:

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

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

}

DummyCachedMethods的相关功能是:

@Cacheable(value = { "accountSettingsCache" }, key = "new String(\"currentUser\")")
  public String getCurrentUserName() {
    return WebUtils.getCurrentUser().getUsername();
  }

WebUtils.getCurrentUser()只返回SecurityContext中的当前Principal。

但这不起作用,测试没有通过这一行:

  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注释,它确实通过了,但我想这不是我想要的。

我错过了什么?

0 个答案:

没有答案