2012-03-23 93 views
2

這是針對我的整個系統的一些高級Web/Rest測試,由Jetty/Spring提供動力。JUnit測試啓動Jetty,Jetty啓動Spring,可以測試看看Spring應用程序的上下文

我所試圖做的是有一個完全獨立的測試,

  • 啓動碼頭這將啓動
  • 應用程序啓動Spring應用
  • 測試使用的webdriver/RestAssured打應用測試行爲
  • 測試檢查DB已更改的數據

什麼我想d o是在一個JVM中運行整個事件,即我正在啓動一個org.eclipse.jetty.server.Server。
這是因爲它的簡單,避免了外部依賴性測試(如啓動碼頭)

這一切都很酷,但我恨,我必須手動檢查DB ......我想用我的DAO(或者可能是服務層)類,所以我不重寫DB代碼。

因爲我的DAO已經在Spring的Jetty實例中作爲測試用例在相同的JVM中啓動,所以我想抓取該ApplicationContext,然後拉出我的DAO Bean。

因爲測試不是每個說的「Spring」測試,所以我有點卡住了獲取ApplicationContext。

人們對如何做到這一點有任何想法?

+1

爲什麼不在測試中建立另一個上下文並使用dao類的不同實例?使用jetty插件描述的場景聽起來像Maven集成測試(故障安全插件)。 – mrembisz 2012-03-23 07:18:44

+0

謝謝,但我特意避開Maven插件作爲一個實驗,使測試自成體系......此刻,您可以像運行其他任何測試一樣運行junit測試,而不需要maven或任何其他構建工具來管理事件......這是來自Mavens集成測試模型在許多項目中經歷的痛苦。我可能會把它移到Gradle,所以我可以在不同類型的測試之間進行更多的分離,而不是maven提供的。 – sMoZely 2012-03-23 22:16:56

回答

2

我認爲在jetty中訪問spring上下文是不可能的,如果它正常啓動的話,如果你使用了一些嵌入式服務器,它可能會工作。

但我覺得有更簡單的解決方案:

  • 使用第二(不同的)彈簧試驗背景下,這可能比「正常」的一個更小的,因爲你並不需要所有的服務和控制器,或
  • 在您的服務器中添加一些json或webservice查詢接口,它只是簡單地從數據庫返回請求的結果。然後,您可以通過服務器中的該接口從您的測試中訪問數據庫。 - 我認爲你只需要兩個或三個不同的查詢每個實體,所以它應該沒有太多的工作,(但我更喜歡另一種解決方案)。
+0

感謝@Ralph,當應用程序服務器實例與測試分開的JVM中時,我已經在不同的項目中使用了這兩種方法。但是因爲我在同一個JVM中啓動了Jetty,所以我很想知道Spring中是否有掛鉤可以使用。 第一個選項可以正常工作,但只適用於連接到像DB這樣的共享資源。假設我需要將內存中的某些內容掛接到服務層,那麼第一個選項會下降。 第二個選擇是更努力,我試圖通過在一個JVM中運行所有東西來避免。 – sMoZely 2012-03-23 22:27:43

+1

你也可以在Arquillian上有一個鎖http://www.jboss.org/arquillian - 我不知道這對於這個場景是否有幫助,但它可以以某種方式將測試與EJB/CDI容器連接起來,mabye它可以與春天也是。 – Ralph 2012-03-24 08:44:28

+0

還沒有使用Arquillian,因爲我沒有在做EJB/CDI的東西,我也不會使用JBoss。鎖定它是迄今爲止的最佳答案...暫且我將使用第一個解決方案,它可以正常工作,並允許我重新使用我的測試,如果我想使用遠程碼頭實例(我可以控制系統道具)。我仍然想弄清楚我是否可以掛鉤到相同的應用上下文中,就像暫時的思考練習一樣。 – sMoZely 2012-03-25 20:18:16

2

@ Ralph的答案是最好的 - 在測試中使用單獨的彈簧環境。理想情況下,您應該將所有DAO bean及其依賴關係重構爲單獨的dao-beans.xml,您可以將其包含在主應用程序上下文和測試環境中。

或者,您可以使用Spring Remoting將DAO bean從通過RMI或Jetty HTTP服務器通過添加ServiceExporter豆你的(真正的)應用程序上下文

<bean name="daoExporter" 
     class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> 
    <property name="service"> 
     <ref bean="dao" /> 
    </property> 
    <property name="serviceInterface" value="com.example.IDao" /> 
</bean> 

和網絡定製的Spring遠程的servlet。XML

<servlet> 
    <servlet-name>daoServiceExporter</servlet-name> 
    <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class> 
</servlet> 

<servlet-mapping> 
    <servlet-name>daoServiceExporter</servlet-name> 
    <url-pattern>/remoting/dao</url-pattern> 
</servlet-mapping> 

然後將其導入到你的測試方面

<bean id="dao" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> 
    <property name="serviceInterface" value="com.example.IDao" /> 
    <property name="serviceUrl" value="http://localhost:8080/remoting/dao"/> 
</bean> 

這隻有在例如一個更好的答案加載Spring上下文需要很長時間,或者您可能有一些必須保持單身的bean。

+0

對於使用Spring Remoting的想法+1,這比我的「手寫」json想法更好。 – Ralph 2012-03-23 10:54:35

+0

不錯的解決方案,與上面的註釋類似,DAO通常很容易在單獨的spring應用程序上下文中啓動,因爲它們只是共享一個數據庫。 但是,這將是一個很好的方式來導出比DB更多的服務。 – sMoZely 2012-03-23 22:33:53

相關問題