启用 Tiles 后 StrutsTestCase 中的 NPE

发布于 2024-11-04 03:17:43 字数 2383 浏览 4 评论 0原文

我开发了一些扩展 org.apache.struts2.StrutsTestCase 的 JUnit 测试。我在 struts.apache 上使用了教程。 org 作为我的起点。

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

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

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

日志显示 Struts 2 Action 正在成功执行,直到它尝试将其交给 TilesResult.doExecute。

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

这有道理吗?

我正在使用 Struts 2.2.1.1 和 Struts 发行版中包含的与tile相关的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 一起使用的教程页面,但 SourceForge 页面 还没有自 Struts 1.3 以来没有更新 另外,StrutsTestCase 和 MockStrutsTestCase 之间有什么区别

I developed some JUnit tests that extend org.apache.struts2.StrutsTestCase. I used the tutorial on struts.apache.org as my starting point.

Everything was working fine until I modified my simple web application to use Tiles. I have Tiles working fine in the app but now my Action test cases have stopped working.

I'm getting NullPointerException at org.apache.struts2.views.tiles.TilesResult.doExecute when I run the following line of code:

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

The log shows the Struts 2 Action is executing succesfully until it tries to hand it off to TilesResult.doExecute.

I suspect it is because the tests run outside of the container and the tiles.xml is only referenced in the web.xml and therefore my StrutsTestCase tests don't know where to find the definitions in tiles.xml.

Is this making sense?

I'm using Struts 2.2.1.1 and the tiles related jars (v. 2.0.6) included in the Struts distribution.

I'll include a code snippet from my StrutsTestCase but please note everything runs successfully when I run the app from the browser in Tomcat, it only fails when I run the StrutsTestCase outside of Tomcat. And the test cases ran successfully before I added 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);
    }
}

Partial stack trace:

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)

Lastly, can anyone explain what the deal is with StrutsTestCase? There's a tutorial page for using it with Struts 2 on struts.apache.org but the SourceForge page for it hasn't been updated since Struts 1.3 Also, what's the difference between StrutsTestCase and MockStrutsTestCase

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

妄司 2024-11-11 03:17:43

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

<listener>
    <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</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] 请参阅

I imagine you're initialising tiles with a listener:

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

You need to initialise that Listener in your tests. I found a few others with the same issue [1].
The code below is in your class that extends StrutsSpringTestCase. You need to override the setupBeforeInitDispatcher. In the code snippet below, the override sets the applicationContext attribute (also needed if you're using spring) and initialises Tiles (inside the if(tilesApplication) segment, where tilesApplication is a boolean so you can toggle this code on an off based on your whether or not your application runs with 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] See http://depressedprogrammer.wordpress.com/2007/06/18/unit-testing-struts-2-actions-spring-junit/

风尘浪孓 2024-11-11 03:17:43

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

添加以下行

proxy.setExecuteResult(false); 

因此,在 proxy.execute() 之前

It is trying to display the jsp page. So disable by adding ExecuteResult(false) in the code.

So, add the below line

proxy.setExecuteResult(false); 

before proxy.execute()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文