2011-04-28 63 views
3

我开发了一些扩展org.apache.struts2.StrutsTestCase的JUnit测试。我使用struts.apache.org上的tutorial作为我的出发点。在启用Tiles之后的StrutsTestCase中NPE

一切工作正常,直到我修改我的简单的Web应用程序使用瓷砖。我的Tiles在应用程序中工作正常,但现在我的Action测试用例已停止工作。

我在org.apache.struts2.views.tiles.TilesResult.doExecute得到NullPointerException异常,当我运行下面的代码行:

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

日志显示了Struts 2动作被成功地执行,直到它会尝试将其交给TilesResult.doExecute。

我怀疑这是因为测试运行在容器之外,并且tiles.xml仅在web.xml中引用,因此我的StrutsTestCase测试不知道在tiles.xml中的何处找到定义。

这是有道理的吗?

我正在使用Struts 2.2.1.1和Struts发行版中包含的与tiles相关的jar(v.2.0.6)。

我会在我的StrutsTestCase中包含代码片段,但请注意,当我在Tomcat中的浏览器中运行应用程序时,所有内容都能成功运行,但只有在Tomcat之外运行StrutsTestCase时才会失败。在添加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,但是从Struts 1.3开始,SourceForge page for it还没有更新。另外,StrutsTestCase和MockStrutsTestCase之间的区别是什么

+0

我迷迷糊糊翻过了同样的问题之前添加以下行

proxy.setExecuteResult(false); 

。贾斯汀,你是否设法解决并解决它? – mmalmeida 2012-01-27 17:24:57

+0

@wild_oscar,不幸的是,没有。祝你好运 – Justin 2012-01-28 01:49:14

+0

@Justin找到了解决办法? – 2013-12-04 14:58:54

回答

3

我想你正在初始化一个侦听器:

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

您需要在测试中初始化该Listener。我发现了一些其他问题相同的问题[1]。 下面的代码在你的类中,它扩展了StrutsSpringTestCase。您需要覆盖setupBeforeInitDispatcher。在下面的代码片段中,覆盖设置applicationContext属性(如果您使用spring,也需要)并初始化Tiles(在if(tilesApplication)段中,其中tilesApplication是布尔值,因此您可以基于您是否您的应用程序运行的瓷砖):

/** 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/

+0

感谢您的回答。我从Struts2转到Spring MVC,因此无法轻易地在我的旧项目中确认这个解决方案。因为这是这个问题收到的唯一答案(它看起来应该起作用),我会继续接受它。非常感谢! – Justin 2012-01-30 14:10:45

+0

我有这个相同的错误,追溯到TilesResult NPE,这解决了我的问题。谢谢! – 2012-09-25 18:11:50

+0

我有同样的问题,但我没有使用Spring,因此,我正在扩展'StrutsJUnit4TestCase' - 在我的情况下会是什么解决方案? – 2013-12-04 14:50:09

1

它试图显示JSP页面。因此,通过在代码中添加ExecuteResult(false)来禁用。

所以,proxy.execute()