2013-12-03 4 views
1

Весной 3.1 я мог бы авторизовать ресурс Jax-RS, который имел «@Scope» («запрос») в мои модульные тесты. Я включил следующее BeanFactoryPostProcessor:Весна 3.2: Единичные испытания @Scope («запрос») больше не работают

не
@Component 
public class MockRequestBeanFactoryPostProcessor implements BeanFactoryPostProcessor { 

public void postProcessBeanFactory(
     ConfigurableListableBeanFactory beanFactory) throws BeansException { 

    beanFactory.registerScope("request", new RequestScope()); 
    MockHttpServletRequest request = new MockHttpServletRequest(); 
    ServletRequestAttributes attributes = new ServletRequestAttributes(request); 
    RequestContextHolder.setRequestAttributes(attributes); 
} 

}

с весной 3.2, первым методом испытаний, который работает работает, но все последующие методы испытаний получают

java.lang.IllegalStateException: запроса нет поток переплета найдено : Вы имеете в виду запрос атрибутов вне фактического веб-запроса или обработки запроса вне исходного потока? Если вы действительно работаете в веб-запросе и все еще получаете это сообщение, ваш код, вероятно, работает за пределами DispatcherServlet/DispatcherPortlet: в этом случае используйте RequestContextListener или RequestContextFilter, чтобы выставить текущий запрос.

Как я могу снова запустить свои тесты?

+0

Пожалуйста, добавьте свой тестовый класс. –

ответ

3

BeanFactoryPostProcessor неисправен, он работает только один раз, и поэтому только одна нить будет иметь (не может использоваться повторно) MockHttpServletRequest.

Перемещение кода, который создает запрос и сохраняет его в RequestContextHolder должен быть перемещен в аннотированный метод @Before и в @After аннотированный метода надо Ыборка RequestContextHolder.

@Before 
public void init() { 
    MockHttpServletRequest request = new MockHttpServletRequest(); 
    ServletRequestAttributes attributes = new ServletRequestAttributes(request); 
    RequestContextHolder.setRequestAttributes(attributes); 
} 

@After 
public void cleanUp() { 
    RequestContextHolder.resetRequestAttributes(); 
} 

Вы все еще нуждаются в BeanFactoryPostProcessor зарегистрировать RequestScope.

+0

Это не работает, потому что Spring автоматически очищает мой тестовый класс до вызова методов @Before. –

+0

Вместо этого вы можете выполнить поиск. Еще одна вещь, которую вы можете добавить/попробовать - добавить аннотацию '@ WebAppConfiguration' к вашему тестовому классу (я предполагаю, что вы используете тестовую поддержку Springs для загрузки и автоустройства). Который должен устранить необходимость в «BeanFactoryPostProcessor» и методах '@ Before' /' @ After'. –

0

Spring 3.2 представил ServletTestExecutionListener, который грубо вводит себя в ваши старые тесты.

Его Javadoc:

TestExecutionListener, который обеспечивает поддержку макета Servlet API для WebApplicationContexts загружаемого Spring Framework TestContext.

В частности, ServletTestExecutionListener устанавливает нити локального состояния через RequestContextHolder Spring Web во время подготовки экземпляра тестирования и перед каждым методом испытаний и создает MockHttpServletRequest, MockHttpServletResponse и ServletWebRequest на основе настоящего MockServletContext в WebApplicationContext. Этот слушатель также гарантирует, что MockHttpServletResponse и ServletWebRequest могут быть введены в тестовый экземпляр, и как только тест будет завершен, этот прослушиватель очистит локальное состояние потока.

Обратите внимание, что ServletTestExecutionListener включен по умолчанию, но не принимает никаких действий, если ApplicationContext, загруженный для текущего теста, не является WebApplicationContext.

Проблема в том, что последний абзац является ложью. Правда, этот класс не начинает помогать вам, если вы не вносите изменения в конфигурацию, но он будет с радостью сбросить запрос после каждого теста, несмотря ни на что.

Слушатель можно отключить, добавив @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class }) в тестовый класс. (Фактический набор слушателей, которые вы можете редактировать по мере необходимости.)

В качестве альтернативы вы можете установить @WebAppConfiguration и удалить MockRequestBeanFactoryPostProcessor, а также другие унаследованные рабочие процессы, такие как MockServletContextAwareProcessor.

+0

Я бы пошел с дефолтом и кругом вокруг (меньше кода для поддержания :)). Хорошая уловка при перезагрузке, вы можете захотеть зарегистрировать ошибку/JIRA (http://jira.springsource.org) для этого. –

+0

@ M.Deinum Thing, согласно http://stackoverflow.com/questions/8878190/running-unit-tests-on-the-server-jax-rs/9041446#9041446, я делаю некоторые интересные вещи с ServletContexts и модульные тесты. Мне нужно установить путь к ресурсу, но '@ WebAppConfiguration.value' фиксируется во время компиляции. Поэтому я думаю, что продолжу использовать свой собственный ServletContextAwareProcessor. В любом случае, когда я запускаю junit вручную (программно через JUnitCore), встроенный SCAP не работает ('@ WAC' ошибка?), Поэтому у меня нет выбора. Но, кажется, я могу использовать '@ WAC' и мой собственный SCAP вместе, пропуская« RequestBeanFactoryPostProcessor ». –

Смежные вопросы