NPE в StrutsTestCase после включения тайлов - PullRequest
3 голосов
/ 28 апреля 2011

Я разработал некоторые тесты JUnit, которые расширяют org.apache.struts2.StrutsTestCase. В качестве отправной точки я использовал учебник на struts.apache.org.

Все работало нормально, пока я не изменил свое простое веб-приложение для использования Tiles. У меня Tiles работает нормально в приложении, но теперь мои тестовые примеры Action перестали работать.

Я получаю исключение NullPointerException по адресу org.apache.struts2.views.tiles.TilesResult.doExecute, когда я запускаю следующую строку кода:

ActionProxy proxy = getActionProxy("/displaytag.action");

В журнале показано, что действие Struts 2 успешно выполняется до тех пор, пока оно не попытается передать его TilesResult.doExecute.

Я подозреваю, что это потому, что тесты выполняются вне контейнера, а файл tile.xml упоминается только в файле web.xml, и поэтому мои тесты StrutsTestCase не знают, где найти определения в файле tile.xml.

Имеет ли это смысл?

Я использую Struts 2.2.1.1 и jar-файлы, относящиеся к плиткам (v. 2.0.6), включенные в дистрибутив Struts.

Я включу фрагмент кода из моего StrutsTestCase, но, пожалуйста, обратите внимание, что все запускается успешно, когда я запускаю приложение из браузера в Tomcat, это происходит только при запуске StrutsTestCase вне Tomcat. И тестовые примеры прошли успешно, прежде чем я добавил Tiles.

public class TagActionTest extends StrutsTestCase {

static Logger logger = Logger.getLogger(TagActionTest.class);

public void testCreateTagFail() throws Exception {
    logger.debug("Entering testCreateTagFail()");

    try {
        request.setParameter("name", "");

        ActionProxy proxy = getActionProxy("/createtag.action");

        TagAction tagAction = (TagAction) proxy.getAction();

        proxy.execute();

        assertTrue("Problem There were no errors present in fieldErrors but there should have been one error present", tagAction.getFieldErrors().size() == 1);
        assertTrue("Problem field 'name' not present in fieldErrors but it should have been",
                tagAction.getFieldErrors().containsKey("name") );
    } catch (Exception e) {
        logger.debug("Error running testCreateTagFail()");
        e.printStackTrace();

        assertTrue("Error running testCreateTagFail()", false);
    }
}

Частичная трассировка стека:

java.lang.NullPointerException
at org.apache.struts2.views.tiles.TilesResult.doExecute(TilesResult.java:105)
at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:373)

И, наконец, кто-нибудь может объяснить, что происходит со StrutsTestCase? На Struts.apache.org есть страница учебника по его использованию со Struts 2, но страница SourceForge для него не обновлялась со времен Struts 1.3. Кроме того, в чем разница между StrutsTestCase и MockStrutsTestCase

Ответы [ 2 ]

3 голосов
/ 30 января 2012

Я предполагаю, что вы инициализируете тайлы с помощью слушателя:

<listener>
    <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>

Вам нужно инициализировать этот слушатель в ваших тестах.Я нашел несколько других с такой же проблемой [1].Код ниже в вашем классе, который расширяет StrutsSpringTestCase.Вам нужно переопределить setupBeforeInitDispatcher.В приведенном ниже фрагменте кода переопределение устанавливает атрибут applicationContext (также необходимо, если вы используете spring) и инициализирует Tiles (внутри сегмента if (tileApplication), где tileApplication является логическим значением, поэтому вы можете переключать этот код в выключенное состояние наваше ли приложение работает с плитками):

    /** Overrides the previous in order to skip applicationContext assignment: context is @autowired
 * @see org.apache.struts2.StrutsSpringTestCase#setupBeforeInitDispatcher()
 **/
@Override
protected void setupBeforeInitDispatcher() throws Exception {
    //init context

    servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext);

    if(tilesApplication){
        servletContext.addInitParameter(BasicTilesContainer.DEFINITIONS_CONFIG, "WEB-INF/tiles.xml");
        final StrutsTilesListener tilesListener = new StrutsTilesListener();
        final ServletContextEvent event = new ServletContextEvent(servletContext);
        tilesListener.contextInitialized(event);
    }

}

[1] См. http://depressedprogrammer.wordpress.com/2007/06/18/unit-testing-struts-2-actions-spring-junit/

1 голос
/ 26 февраля 2014

Он пытается отобразить страницу JSP.Поэтому отключите, добавив в код ExecuteResult (false).

Итак, добавьте следующую строку

proxy.setExecuteResult(false); 

перед proxy.execute()

...