2012-03-23 48 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

相关问题