Testing Request- and Session-scoped Beans

Spring 自早期就开始支持 Request- and session-scoped beans ,并且你可以通过按照以下步骤测试你的请求作用域和会话作用域 bean:

  • 通过使用 @WebAppConfiguration`注解测试类,确保为测试加载 `WebApplicationContext

  • 将模拟请求或会话注入你的测试实例,并根据需要准备测试固定装置。

  • 调用从已配置的 `WebApplicationContext`检索到的 Web 组件(使用依赖注入)。

  • 对仿真进行断言。

以下代码段显示了登录用例的 XML 配置。请注意,userService bean 依赖于基于请求的 loginAction bean。此外,LoginAction 是通过使用 SpEL expressions 实例化的,后者从当前 HTTP 请求中检索用户名和密码。在我们的测试中,我们希望通过 TestContext 框架管理的模拟配置这些请求参数。以下清单显示了此用例的配置:

Request-scoped bean configuration
<beans>

	<bean id="userService" class="com.example.SimpleUserService"
			c:loginAction-ref="loginAction"/>

	<bean id="loginAction" class="com.example.LoginAction"
			c:username="#{request.getParameter('user')}"
			c:password="#{request.getParameter('pswd')}"
			scope="request">
		<aop:scoped-proxy/>
	</bean>

</beans>

RequestScopedBeanTests 中,我们将 UserService(即测试主题)和 MockHttpServletRequest 都注入到我们的测试实例中。在我们的 requestScope() 测试方法中,我们通过在提供的 MockHttpServletRequest 中设置请求参数来设置我们的测试装置。当 loginUser() 方法在我们的 userService 上调用时,我们确信用户服务可以访问当前 MockHttpServletRequest 的请求范围 loginAction(即,我们刚刚在其中设置参数的那个)。然后,我们可以基于用户名和密码的已知输入对结果执行断言。以下列表显示了如何执行此操作:

  • Request-scoped bean test

  • Kotlin

@SpringJUnitWebConfig
class RequestScopedBeanTests {

	@Autowired UserService userService;
	@Autowired MockHttpServletRequest request;

	@Test
	void requestScope() {
		request.setParameter("user", "enigma");
		request.setParameter("pswd", "$pr!ng");

		LoginResults results = userService.loginUser();
		// assert results
	}
}
@SpringJUnitWebConfig
class RequestScopedBeanTests {

	@Autowired lateinit var userService: UserService
	@Autowired lateinit var request: MockHttpServletRequest

	@Test
	fun requestScope() {
		request.setParameter("user", "enigma")
		request.setParameter("pswd", "\$pr!ng")

		val results = userService.loginUser()
		// assert results
	}
}

以下代码片段类似于我们之前看到的请求范围 Bean 的代码片段。但是,这次 userService Bean 依赖于会话范围的 userPreferences Bean。请注意,UserPreferences Bean 通过使用从当前 HTTP 会话中检索主题的 SpEL 表达式实例化。在我们的测试中,我们需要在 TestContext 框架管理的模拟会话中配置一个主题。以下示例显示了如何执行此操作:

Session-scoped bean configuration
<beans>

	<bean id="userService" class="com.example.SimpleUserService"
			c:userPreferences-ref="userPreferences" />

	<bean id="userPreferences" class="com.example.UserPreferences"
			c:theme="#{session.getAttribute('theme')}"
			scope="session">
		<aop:scoped-proxy/>
	</bean>

</beans>

SessionScopedBeanTests 中,我们将 UserServiceMockHttpSession 注入到我们的测试实例中。在我们 sessionScope() 测试方法中,我们通过设置所提供的 MockHttpSession 中预期的 theme 属性来设置我们的测试装置。当 processUserPreferences() 方法在我们的 userService 上被调用时,我们确保用户服务有权访问当前 MockHttpSession 的会话范围的 userPreferences,并且我们可以基于经过配置的主题对结果执行断言。以下示例展示了如何执行此操作:

  • Session-scoped bean test

  • Kotlin

@SpringJUnitWebConfig
class SessionScopedBeanTests {

	@Autowired UserService userService;
	@Autowired MockHttpSession session;

	@Test
	void sessionScope() throws Exception {
		session.setAttribute("theme", "blue");

		Results results = userService.processUserPreferences();
		// assert results
	}
}
@SpringJUnitWebConfig
class SessionScopedBeanTests {

	@Autowired lateinit var userService: UserService
	@Autowired lateinit var session: MockHttpSession

	@Test
	fun sessionScope() {
		session.setAttribute("theme", "blue")

		val results = userService.processUserPreferences()
		// assert results
	}
}