junit不能測struts的action,httpunit也只能測servlet。用struts作項目的時候無法方便的對action層做單元測試一直是我的心頭大恨?,F在好了,我們有了StrutsTestCase。按照網上的介紹,StrutsTestCase用起來應該是非常簡單的,只要下了jar包回來引用到工程里面就可以了。實際上可能也差不多--如果你運氣不象我這么臭的話。
在sourceforge上隨便挑其中一個鏡象的下載地址:
http://aleron.dl.sourceforge.net/sourceforge/strutstestcase/strutstest213-1.2_2.4.zipflashget回來,放到jbuilder的userhome里面,找一個struts action創建test case,創建的時候吧test case的基類改為 MockStrutsTestCase,測試的方法一個都不用選(因為我們是要針對action的具體每一個邏輯分支測試而不是具體的某一個方法)。創建成功后添加一個測試:
public void testSuccessfulRefresh()
{
setRequestPathInfo("/RefreshSystemData");
actionPerform();
verifyForward("success");
}嘿嘿,我精心挑了一個沒有參數的action來實驗。
一切看起來很順利。run test,噩夢開始了:
java.lang.NullPointerException
at servletunit.struts.MockStrutsTestCase.getActionServlet(MockStrutsTestCase.java:331)
at servletunit.struts.MockStrutsTestCase.tearDown(MockStrutsTestCase.java:130)
at hospital.tongren.oa.system.action.TestRefreshSystemDataAction.tearDown(TestRefreshSystemDataAction.java:34)
...(Click for full stack trace)...還好我沒有開音箱,不然又是一大炮轟出來。
看來要調試了,先去同一個地方下了StrutsTestCase原碼回來
http://aleron.dl.sourceforge.net/sourceforge/strutstestcase/strutstest-213-src.zip加進userhome里面的source。debug進去,跟到org.apache.struts.action.ActionServlet里面,出錯的地方是:
InputStream input =
getServletContext().getResourceAsStream("/WEB-INF/web.xml");try {
digester.parse(input);} catch (IOException e) {
....input 為空指針。不知道為什么ServletContextSimulator在模擬ServletContext的時候沒能夠正確的找到webmodule的位置。上網搜了好一會兒文檔,在 http://strutstestcase.sourceforge.net/api/servletunit/struts/MockStrutsTestCase.html 中發現了這樣一段:
NOTE: By default, the Struts ActionServlet will look for the file WEB-INF/struts-config.xml, so you must place the directory that contains WEB-INF in your CLASSPATH. ...
先照它說的試試把webmodule路徑放進classpath中,沒有用。
往下看,發現了這個好東東:setContextDirectory。在startup中加一句:this.setContextDirectory(new File("E:\\projectPath\\webModulePath\\"));
終于把那個空指針給過了。但是報一個新的異常:
junit.framework.AssertionFailedError: received error 400 : Invalid path /RefreshSystemData was requested
at servletunit.HttpServletResponseSimulator.sendError(HttpServletResponseSimulator.java:463)
at org.apache.struts.action.RequestProcessor.processMapping(RequestProcessor.java:684)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:242)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
at servletunit.struts.MockStrutsTestCase.actionPerform(MockStrutsTestCase.java:394)
at hospital.tongren.oa.system.action.TestRefreshSystemDataAction.testSuccessfulRefresh(TestRefreshSystemDataAction.java:51)
...(Click for full stack trace)...
找不到strutsconfig里面配置的path。strutsconfig是在web.xml里面配置的,應該還是web.xml沒找到造成的,那么就指定strutsconfig文件的位置咯:
setConfigFile("E:\\......\\struts-config.xml");終于可以運行起來了。
隨后發現,如果 setServletConfigFile("E:\\....\\WEB-INF\\web.xml");的話MockStrutsTestCase也能夠根據web.xml中的配置找到strutsconfig文件。
最后把上面用到的絕對地址E:\\...全部改為相對地址:
setContextDirectory(new File("modulePath\\"));
setServletConfigFile("modulePath\\WEB-INF\\web.xml");
// this.setConfigFile("modulePath\\WEB-INF\\config\\system\\struts-config.xml");血吐完了,繼續郁悶,為什么別人都不用配置的這么麻煩呢?到底我做錯了什么,還是jbuilder的錯?
CactusStrutsTestCase也沒配起,好像要加個什么包吧,再看看先。
[點擊此處收藏本文]發表于 2005年01月22日 4:04 PMemu 發表于2005-01-22 8:00 PMhttp://jakarta.apache.org/cactus/getting_started.html 中有詳細的說明。感覺確實復雜了一點?,F在進展是:
org.apache.cactus.util.ChainedRuntimeException: Failed to get the test results at [http://localhost:8083/TongRenOA/ServletRedirector]
at org.apache.cactus.internal.client.connector.http.DefaultHttpClient.doTest_aroundBody0(DefaultHttpClient.java:92)
at org.apache.cactus.internal.client.connector.http.DefaultHttpClient.doTest_aroundBody1$advice(DefaultHttpClient.java:206)
at org.apache.cactus.internal.client.connector.http.DefaultHttpClient.doTest(DefaultHttpClient.java)
at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runWebTest(HttpProtocolHandler.java:159)
at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runTest_aroundBody0(HttpProtocolHandler.java:80)
at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runTest_aroundBody1$advice(HttpProtocolHandler.java:206)
at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runTest(HttpProtocolHandler.java)
at org.apache.cactus.internal.client.ClientTestCaseCaller.runTest(ClientTestCaseCaller.java:144)
at org.apache.cactus.internal.AbstractCactusTestCase.runBareClient(AbstractCactusTestCase.java:215)
at org.apache.cactus.internal.AbstractCactusTestCase.runBare(AbstractCactusTestCase.java:133)
...(Click for full stack trace)...
下班先。