我开发了一些扩展org.apache.struts2.StrutsTestCase的JUnit测试。我以struts.apache.org上的tutorial为起点。

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

运行以下代码行时,我在org.apache.struts2.views.tiles.TilesResult.doExecute上收到NullPointerException:

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

日志显示Struts 2 Action成功执行,直到尝试将其传递给TilesResult.doExecute。

我怀疑这是因为测试在容器外部运行,而tile.xml仅在web.xml中引用,因此我的StrutsTestCase测试不知道在tile.xml中的定义位置。

这有意义吗?

我正在使用Struts 2.2.1.1以及Struts发行版中与tile相关的jars(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有什么区别?

最佳答案

我想您正在使用侦听器初始化图块:

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

您需要在测试中初始化该监听器。我发现了其他一些具有相同问题的问题[1]。
下面的代码在您的扩展StrutsSpringTestCase的类中。您需要覆盖setupBeforeInitDispatcher。在下面的代码片段中,重写将设置applicationContext属性(如果使用spring时也需要),并初始化Tiles(在if(tilesApplication)段中,tilesApplication是一个布尔值,因此您可以基于您的应用程序是否使用tile):
    /** 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/

关于junit - 启用图块后,StrutsTestCase中的NPE,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5823709/

10-10 06:41