1

一部のユーザー データを保持するセッション スコープ 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 から現在のプリンシパルを返すだけです。

しかし、これは機能しません。テストは次の行でパスしません。

  assertTrue(methods.getCurrentUserName().equals(((CustomUserDetails) authentication2.getPrincipal()).getUsername()));

メソッド呼び出しはキャッシュされるため、James ではなく Johnny を返します。

私のキャッシュ関連の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 アノテーションのコメントを外せば合格ですが、それは私が望むものではないと思います。

何が欠けていますか?

4

0 に答える 0