2011-04-28 65 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()