#junit #struts2 #tiles
#юнит #struts2 #плитки #junit
Вопрос:
Я разработал несколько тестов JUnit, которые расширяют org.apache.struts2.StrutsTestCase. Я использовал руководство по struts.apache.org в качестве отправной точки.
Все работало нормально, пока я не изменил свое простое веб-приложение для использования Tiles. У меня в приложении Tiles работают нормально, но теперь мои тестовые примеры действий перестали работать.
Я получаю исключение NullPointerException в org.apache.struts2.views.tiles.TilesResult.Выполняется при запуске следующей строки кода:
ActionProxy proxy = getActionProxy("/displaytag.action");
Журнал показывает, что действие Struts 2 выполняется успешно до тех пор, пока оно не попытается передать его TilesResult.doExecute.
Я подозреваю, что это потому, что тесты выполняются вне контейнера и tiles.xml упоминается только в web.xml и поэтому мои тесты StrutsTestCase не знают, где найти определения в tiles.xml .
Есть ли в этом смысл?
Я использую Struts 2.2.1.1 и связанные с плиткой jar (версия 2.0.6), включенные в дистрибутив Struts.
Я включу фрагмент кода из моего StrutsTestCase, но, пожалуйста, обратите внимание, что все выполняется успешно, когда я запускаю приложение из браузера в Tomcat, сбой происходит только при запуске StrutsTestCase за пределами Tomcat. И тестовые примеры успешно выполнялись до того, как я добавил плитки.
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 есть страница руководства по его использованию с Struts 2.org но страница SourceForge для нее не обновлялась со времен Struts 1.3 Кроме того, в чем разница между StrutsTestCase и MockStrutsTestCase
Комментарии:
1. Я наткнулся на ту же проблему. Тебе удалось недооценить и решить проблему, Джастин?
2. @wild_oscar, к сожалению, нет. удачи
3. @Justin нашел какое-либо решение?
Ответ №1:
Я полагаю, вы инициализируете tiles с помощью прослушивателя:
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>
Вам необходимо инициализировать этот прослушиватель в ваших тестах. Я нашел несколько других с такой же проблемой [1].
Приведенный ниже код находится в вашем классе, который расширяет StrutsSpringTestCase. Вам необходимо переопределить setupBeforeInitDispatcher. В приведенном ниже фрагменте кода переопределение устанавливает атрибут ApplicationContext (также необходимый, если вы используете spring) и инициализирует Tiles (внутри сегмента if(tilesApplication), где tilesApplication является логическим значением, поэтому вы можете переключить этот код на off в зависимости от того, выполняется ли ваше приложение с tiles ):
/** 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. спасибо за ответ. с тех пор я перешел с Struts2 на Spring MVC и, следовательно, не могу легко подтвердить это решение в моем старом проекте. поскольку это единственный ответ, полученный на этот вопрос (и, похоже, он должен сработать), я собираюсь пойти дальше и принять его. большое спасибо!
2. У меня была такая же ошибка, я отследил ее до TilesResult NPE, и это устранило мою проблему. Спасибо!
3. У меня такая же проблема, но я не использую Spring и, следовательно, я расширяю
StrutsJUnit4TestCase
— каким будет решение в моем случае?
Ответ №2:
Он пытается отобразить страницу jsp. Поэтому отключите, добавив ExecuteResult(false) в коде.
Итак, добавьте строку ниже
proxy.setExecuteResult(false);
перед proxy.execute()