FrontPage

2008/03/13からのアクセス回数 15911

Spring-MVCでspringのsession scopeオブジェクトをテストしたい

Spring 2.0から導入されたsession scopeオブジェクトは、DispatcherServletで処理されるため MockHttpServletRequestを使った単体テストでは、bean定義ファイルでscope="session"で 定義されたsession scopeオブジェクトのsession単位での持ち回りのテストができません。

session scopeオブジェクトに必要なもの

session scopeオブジェクトのテストには、

AbstractTransactionalSpringWebContextTestsを追加

GenericWebApplicationContextをcreateApplicationContextメソッドで返すTestCaseとして AbstractTransactionalSpringWebContextTestsを追加しました。

AbstractTransactionalSpringWebContextTestsのcreateApplicationContextは以下の通りです。

	protected ConfigurableApplicationContext createApplicationContext(final String[] locations) {
		GenericWebApplicationContext context = 
				new GenericWebApplicationContext(
						new GenericApplicationContext().getDefaultListableBeanFactory());
		context.setServletContext(new MockServletContext());
		customizeBeanFactory(context.getDefaultListableBeanFactory());
		createBeanDefinitionReader(context).loadBeanDefinitions(locations);
		context.refresh();
		// StaticWebApplicationContext のpostProcessBeanFactoryと同じ処理を追加
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
		beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope(false));
		beanFactory.registerScope(WebApplicationContext.SCOPE_GLOBAL_SESSION, 
				new SessionScope(true));

		return context;
	}

beginRequest, endRequestメソッドの追加

HTTPリクエストの前後にRequestContextFilterと同様の処理行うメソッド、beginRequest, endRequestメソッドをAbstractTransactionalSpringWebContextTestsに定義しました。

beginRequestメソッドは、

	public void beginRequest(MockHttpServletRequest req) {		
		ServletRequestAttributes attributes = new ServletRequestAttributes(req);
		req.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes);
		RequestContextHolder.setRequestAttributes(attributes);
		
		ServletContext sc = req.getSession().getServletContext();
		GenericWebApplicationContext wac = (GenericWebApplicationContext)getApplicationContext();
		wac.setServletContext(sc);
		sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, (GenericWebApplicationContext)getApplicationContext());
		
	}

endRequestメソッドは、

	public void endRequest(MockHttpServletRequest req) {
		ServletRequestAttributes attributes = (ServletRequestAttributes) req
				.getAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE);
		ServletRequestAttributes threadAttributes = (ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes();
		if (threadAttributes != null) {
			// We're assumably within the original request thread...
			if (attributes == null) {
				attributes = threadAttributes;
			}
			RequestContextHolder.setRequestAttributes(null);
			LocaleContextHolder.setLocale(null);
		}
		if (attributes != null) {
			attributes.requestCompleted();
			if (logger.isDebugEnabled()) {
				logger.debug("Cleared thread-bound request context: " + req);
			}
		}
	}

と定義しました。

テストメソッドの記述方法

session scopeオブジェクトのテストメソッドを定義するには、

HTTP要求の前後処理例

以下にMemberOpsControllerを例にHTTP要求の前後処理の仕方を示します。

		MemberOpsController	memberOpsController = 
				(MemberOpsController)getApplicationContext().getBean("memberOpsController");
		ModelAndView mv = null;
		beginRequest(req);
		mv = memberOpsController.handleRequest(req,new MockHttpServletResponse());
		endRequest(req);

セッション情報の持ち回り

同一セッションは、つぎのようにして持ち回ることができます。

		HttpSession session =  req.getSession();
		req = new MockHttpServletRequest("POST","memberops/list.htm");
		req.setSession(session);

これで、session scopeオブジェクトの単体テストができるようになります。

コメント

皆様のご意見、ご希望をお待ちしております。


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
SmartDoc