unit testing与Spring的集成testing

我正在开发一个Spring MVC项目,并对源代码树中的所有组件进行了unit testing。

例如,如果我有一个控制器HomeController ,需要注入一个LoginService ,那么在我的unit testingHomeControllerTest我只是简单地实例化对象(在Spring之外)并注入属性:

 protected void setUp() throws Exception { super.setUp(); //... controller = new HomeController(); controller.setLoginService( new SimpleLoginService() ); //... } 

这对于testing每个组件作为一个单独的单元非常适用 – 除了现在我有几十个类在项目中,写了一个类并写了一个成功的unit testing之后,我一直忘记更新我的Spring MVC上下文文件部署应用程序中的实际接线。 我发现当我将项目部署到Tomcat并从非接线的bean中find一堆NullPointers时,我忘了更新上下文文件。

所以,这是我的问题:

  1. 这是我的第一个Spring项目 – 正如我所做的为单个bean创buildunit testing是正常的,然后创build第二套testing(集成testing)来testing一切与实际应用程序上下文的预期一致吗? 有没有一个确定的最佳实践呢?

  2. 另外,如何将unit testing和集成testing分开? 我有所有的源代码在src ,unit testing在test – 应该有第二个testing文件夹(如test-integration )集成testing用例?

既然这是我的第一个春季项目,我很好奇别人通常会怎么做这样的事情 – 而不是重新发明轮子,而是问问其余的社区。

我不能说是最好的做法,但这是我过去所做的。

unit testing:

  • 为非平凡的bean创buildunit testing(即,大部分Spring相关的bean)
  • 在实际情况下使用Mocks进行注入服务(即,如果不是全部的话)。
  • 在项目test目录中对这些testing使用标准的命名约定。 使用TestTestCase作为类名的前缀或后缀似乎被广泛使用。

集成testing:

  • 创build一个AbstractIntegrationTestCase ,设置一个Spring WebApplicationContext用于整合testing类。
  • test目录中使用集成testing的命名约定。 我已经使用IntTestIntegrationTest作为这些testing的前缀或后缀。

设置三个Ant test目标:

  1. 全部testing(或任何你想命名它):运行单位和综合testing
  2. testing:运行unit testing(仅仅因为test似乎是unit testing最常用的用法
  3. testing集成:运行集成testing。

如上所述,您可以使用对您的项目有意义的命名约定。

至于把单元从集成testing分离到一个单独的目录中,只要开发人员和他们的工具能够轻松地find并执行它们,我不认为这很重要。

作为一个例子,我和Spring一起工作的最后一个Java项目使用了上面所描述的,集成testing和unit testing都在同一个test目录中。 另一方面,Grails项目在通用testing目录下明确地将单元和集成testing目录分开。

几个孤立点:

是的,这是Springtesting的常用方法 – 单独testingunit testing和集成testing,前者不加载任何Spring上下文。

对于你的unit testing,也许考虑嘲笑,以确保你的testing集中在一个孤立的模块。

如果你正在进行testing,那么他们不是真正的unit testing。 他们是集成testing,你使用新的而不是dependency injection来连接依赖关系。 当您的生产应用程序使用Spring时浪费时间和重复的工作!

基本的集成testing来调出你的Spring上下文是有用的。

@required注释可以帮助你确保你在你的Spring配线中捕获所需的依赖关系。

也许看看Maven会给你明确的阶段来绑定你的单元和集成testing。 Maven在Spring社区中被广泛使用。

如果你也切换到一个纯粹注释的政权,那么你用@Component,@Controller,@Service和@Repository注释你的所有bean,那么很多繁琐的双重保留与spring都会消失。 只需添加@Autowired到你需要注入的属性。

参见春季参考手册的第3.11节。 http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config

在相关说明中,我们一直在使用KenG描述的部门/ Integratriontesting。 在我最近的制度中,我们也引入了第三个“类别”testing,“ComponentTests”。 这些使用全弹簧布线运行,但使用有线存根实现(在春季使用组件扫描filter和注释)。

我们这样做的原因是因为对于某些“服务”层来说,最终会出现大量的手动编码布线逻辑来手工连接bean,有时还会有大量可笑的模拟对象。 5线testing的100线接线并不less见。 组件testing缓解了这个问题。

使用InitializingBean接口(实现一个方法“afterPropertiesSet”)或为bean指定一个init方法。 InitializingBean通常更简单,因为您不需要记住将init方法添加到bean中。

使用afterPropertiesSet来确保一切都被注入为非null,如果它为null,则抛出一个Exception。

当我为Web应用程序创build集成testing时,我把它们放在一个单独的目录中。 它们使用jUnit或TestNG构build,并使用Selenium等与用户相似的网页进行交互。 循环将如下所示:编译,运行unit testing,构buildWeb应用程序,将其部署到正在运行的服务器,执行testing,取消部署应用程序并报告结果。 这个想法是testing整个系统。

关于unit testing与集成testing分开运行,我把所有的unit testing放到一个集成testing目录中,并使用这种方法使用IDE / Ant来运行它们。 为我工作。

unit testing和集成testing之间的区别在于,unit testing不一定会加载你的上下文,你关注的是你编写的代码 – 它运行失败很快,也就是说,有和没有例外,嘲弄任何依赖调用。 但是在集成testing的情况下,你需要加载上下文,并像实际场景一样执行端到端的testing。