Testing Request- and Session-scoped Beans
Spring 自早期就开始支持 Request- and session-scoped beans ,并且你可以通过按照以下步骤测试你的请求作用域和会话作用域 bean:
Spring has supported Request- and session-scoped beans since the early years, and you can test your request-scoped and session-scoped beans by following these steps:
-
Ensure that a
WebApplicationContext
is loaded for your test by annotating your test class with@WebAppConfiguration
. -
Inject the mock request or session into your test instance and prepare your test fixture as appropriate.
-
Invoke your web component that you retrieved from the configured
WebApplicationContext
(with dependency injection). -
Perform assertions against the mocks.
以下代码段显示了登录用例的 XML 配置。请注意,userService
bean 依赖于基于请求的 loginAction
bean。此外,LoginAction
是通过使用 SpEL expressions 实例化的,后者从当前 HTTP 请求中检索用户名和密码。在我们的测试中,我们希望通过 TestContext 框架管理的模拟配置这些请求参数。以下清单显示了此用例的配置:
The next code snippet shows the XML configuration for a login use case. Note that the
userService
bean has a dependency on a request-scoped loginAction
bean. Also, the
LoginAction
is instantiated by using SpEL expressions that
retrieve the username and password from the current HTTP request. In our test, we want to
configure these request parameters through the mock managed by the TestContext framework.
The following listing shows the configuration for this use case:
<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
(即,我们刚刚在其中设置参数的那个)。然后,我们可以基于用户名和密码的已知输入对结果执行断言。以下列表显示了如何执行此操作:
In RequestScopedBeanTests
, we inject both the UserService
(that is, the subject under
test) and the MockHttpServletRequest
into our test instance. Within our
requestScope()
test method, we set up our test fixture by setting request parameters in
the provided MockHttpServletRequest
. When the loginUser()
method is invoked on our
userService
, we are assured that the user service has access to the request-scoped
loginAction
for the current MockHttpServletRequest
(that is, the one in which we just
set parameters). We can then perform assertions against the results based on the known
inputs for the username and password. The following listing shows how to do so:
-
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 框架管理的模拟会话中配置一个主题。以下示例显示了如何执行此操作:
The following code snippet is similar to the one we saw earlier for a request-scoped
bean. However, this time, the userService
bean has a dependency on a session-scoped
userPreferences
bean. Note that the UserPreferences
bean is instantiated by using a
SpEL expression that retrieves the theme from the current HTTP session. In our test, we
need to configure a theme in the mock session managed by the TestContext framework. The
following example shows how to do so:
<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
中,我们将 UserService
和 MockHttpSession
注入到我们的测试实例中。在我们 sessionScope()
测试方法中,我们通过设置所提供的 MockHttpSession
中预期的 theme
属性来设置我们的测试装置。当 processUserPreferences()
方法在我们的 userService
上被调用时,我们确保用户服务有权访问当前 MockHttpSession
的会话范围的 userPreferences
,并且我们可以基于经过配置的主题对结果执行断言。以下示例展示了如何执行此操作:
In SessionScopedBeanTests
, we inject the UserService
and the MockHttpSession
into
our test instance. Within our sessionScope()
test method, we set up our test fixture by
setting the expected theme
attribute in the provided MockHttpSession
. When the
processUserPreferences()
method is invoked on our userService
, we are assured that
the user service has access to the session-scoped userPreferences
for the current
MockHttpSession
, and we can perform assertions against the results based on the
configured theme. The following example shows how to do so:
-
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
}
}