Spring поддерживает бины, входящие в область видимости на уровне запроса и сессии, с ранних версий, поэтому вы можете тестировать такие бины, выполнив следующие шаги:

  • Убедитесь, что WebApplicationContext загружен для вашего теста, аннотировав ваш тестовый класс с помощью @WebAppConfiguration.

  • Внедрите имитирующий запрос или сессию в ваш тестовый экземпляр и подготовьте тестовый стенд соответствующим образом.

  • Вызовите ваш веб-компонент, который вы получили из настроенного WebApplicationContext (с помощью внедрения зависимостей).

  • Выполните утверждения относительно объектов-имитаций.

Следующий фрагмент кода показывает XML-конфигурацию для случая использования входа в систему. Обратите внимание, что бин userService имеет зависимость от бина loginAction, находящегося в области видимости на уровне запроса. Кроме того, экземпляр LoginAction создается с помощью выражений на языке SpEL, которые получают имя пользователя и пароль из текущего HTTP-запроса. В нашем тесте нам нужно настроить эти параметры запроса через объект-имитацию, управляемый фреймворком TestContext. В следующем листинге показана конфигурация для этого варианта использования:

Конфигурация бина, входящего в область видимости на уровне запроса
<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. Если для нашего userService будет вызван метод loginUser(), то мы удостоверимся, что специальная служба получит доступ к находящемуся в области видимости на уровне запроса бину loginAction для текущего MockHttpServletRequest (то есть того, в котором мы только что установили параметры). Затем можно выполнить утверждения относительно результатов на основе известных входных данных для имени пользователя и пароля. В следующем листинге показано, как это сделать:

Java
@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();
        // подтверждаем результаты
    }
}
Kotlin
@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()
        // подтверждаем результаты
    }
}

Следующий фрагмент кода похож на тот, который мы видели ранее для бина, входящего в область видимости на уровне запроса. Однако на этот раз бин userService имеет зависимость от бина userPreferences, входящего в область видимости на уровне сессии. Обратите внимание, что экземпляр бина UserPreferences создается с помощью выражения на языке SpEL, которое извлекает тему из текущей HTTP-сессии. В нашем тесте нам нужно настроить тему в имитирующей сессии, управляемой фреймворком TestContext. В следующем примере показано, как это сделать:

Конфигурация бина, входящего в область видимости на уровне сессии
<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() мы настраиваем наш тестовый стенд, устанавливая ожидаемый атрибут theme в предоставленном MockHttpSession. Если для нашего userService будет вызван метод processUserPreferences(), мы удостоверимся, что специальная служба получит доступ к находящемуся в области видимости на уровне сессии бину userPreferences для текущего MockHttpSession и сможем выполнить утверждения относительно результатов на основе сконфигурированной темы. В следующем примере показано, как это сделать:

Java
@SpringJUnitWebConfig
class SessionScopedBeanTests {
    @Autowired UserService userService;
    @Autowired MockHttpSession session;
    @Test
    void sessionScope() throws Exception {
        session.setAttribute("theme", "blue");
        Results results = userService.processUserPreferences();
        // подтверждаем результаты
    }
}
Kotlin
@SpringJUnitWebConfig
class SessionScopedBeanTests {
    @Autowired lateinit var userService: UserService
    @Autowired lateinit var session: MockHttpSession
    @Test
    fun sessionScope() {
        session.setAttribute("theme", "blue")
        val results = userService.processUserPreferences()
        // подтверждаем результаты
    }
}