`
c_fanatic
  • 浏览: 64322 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

如何在单元测试中使用Spring 2.5的自动装配功能---转

阅读更多
Spring 2.5 ships with great support for integration testing through the classes in the org.springframework.test package. These classes allow you to dependency inject your test cases off of your existing Spring configuration, either by using your production Spring configuration file or one you've defined especially for the test case. This post explains how to annotate your JUnit 4 test cases to be autowired, but there's a lot more too the new spring-test.jar and it works with JUnit 3.8 also.
As setup for all the examples, let's assume there is a simple service that can return a String to you. Imaginative, huh?

Java 代码
public class MyService { 
 
   private final String name; 
 
   public MyService(String name) { 
       this.name = name; 
   } 
 
   public String getName() { 
       return name; 
   } 



This service is defined in a Spring XML configuration file as:

Xml代 码
<bean id="myService" class="org.sample.MyService" > 
    <constructor-arg value="simple service" /> 
</bean> 


To have Spring dependency inject our test case, we're going to have to annotate it with a little information. We'll use the standard JUnit @RunWith annotation to tell JUnit to use the Spring TestRunner, the Spring @ContextConfiguration annotation to indicate the TestCase needs injection, and the Spring @Autowired annotation to inject the MyService field by type.

Java 代码
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration 
public final class SimpleAutowireTest { 
 
   @Autowired 
   private MyService service; 
 
   @Test 
   public void testServiceName() { 
       assertEquals("simple service", service.getName()); 
   } 
}  


There are a variety of ways to have Spring run your test. Besides SpringJUnit4ClassRunner.class there are also abstract TestCase objects you can inherit from, including some that will expose the ApplicationContext to you. By default, the spring configuration file for the test case will be [TestName]-context.xml. You can easily override this to point the test at your production configuration file. Also, the @Autowired annotation autowires the field by type. In the case of conflicts, you can specify the bean name using the @Qualifier annotation. Consider the following Spring configuration where there are two beans of type MyService in a file named applicationContext.xml:
Xml代 码
<bean id="deliveryService" class="org.sample.MyService" > 
    <constructor-arg value="delivery service" /> 
</bean> 
 
<bean id="accountingService" class="org.sample.MyService" > 
    <constructor-arg value="accounting service" /> 
</bean> 


The JUnit test now requires the @Qualifier field annotation and a configuration file location as an @ContextConfiguration parameter:

Java 代码
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"applicationContext.xml"}) 
public final class AdvancedAutowireTest { 
 
   @Autowired 
   @Qualifier("deliveryService") 
   private MyService service; 
 
   @Test 
   public void testServiceName() { 
       assertEquals("delivery service", service.getName()); 
   } 



To note: if you point the test to the production Spring configuration, then you're running integration tests and not unit tests. Integration tests are valuable and necessary, but are not always a wholesale replacement of unit tests. There's still value in isolation testing each of the components with mock dependencies. What I like about using Spring for the integration tests is that it validates the Spring mapping at test time. On my projects, we occasionally have the unit tests all passing but the Spring configuration contains a circular dependency, and we don't find out until the build hits QA. A Spring integration test pushes up error time to the test phase, when a developer can take quick action and long before QA is held up.

As is standard with JUnit, each test method runs within its own instance of the TestCase. However, the Spring TestRunner will only create one ApplicationContext for all the instances of the test method. This means that if you're test method destroys the state of a singleton bean, then downstream tests methods using that bean will fail. The way to work around this is to annotate your method with the @DirtiesContext annotation. This tells the Spring TestRunner to reload the context between test methods. For instance, these tests will pass when annotated, but fail when not:

Java 代码
@Autowired 
private MyConfigurableService service; 
 
@Test 
@DirtiesContext 
public void testServiceName1() { 
    assertEquals("configurable service", service.getName()); 
    service.setName("Updating Name"); 

 
@Test 
@DirtiesContext 
public void testServiceName2() { 
    assertEquals("configurable service", service.getName()); 
    service.setName("Updating Name"); 



There's a lot more in spring-test, but this is a good starting point. The transaction annotations look especially promising, including the ability to open and rollback transactions per method. The only reference I know for spring-test is the Javadoc at http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/test/package-summary.html. Those looking for a Spring starter lesson might consult the DZone RefCard.

The dependencies for spring-test are: junit, spring-context, spring-core, spring-beans, spring-tx, and commons-logging. A sample Gradle script for your build is at href="http://svn.assembla.com/svn/SampleCode/spring-test/build.gradle.
All the code for this post (including Gradle build script and IDEA project) is posted at http://svn.assembla.com/svn/SampleCode/spring-test/ and can be downloaded through subversion with the following command:

svn co http://svn.assembla.com/svn/SampleCode/spring-test
分享到:
评论

相关推荐

    spring2.5学习PPT 传智博客

    spring2.5学习PPT 传智博客 01_全面阐释Spring及其各项功能 02_搭建与测试Spring的开发环境 03_编码剖析Spring管理Bean的原理 04_Spring的三种实例化Bean的方式 05_配置Spring管理的bean的作用域 06_Spring...

    spring2.5 学习笔记

    八、 自动装配autowire 13 (一) byName 13 (二) byType 14 (三) 注意 14 九、 生命周期 15 (一) lazy-init/default-lazy-init 15 (二) init-method destroy-method 不要和prototype一起用(了解) 15 第六课:...

    Spring-Reference_zh_CN(Spring中文参考手册)

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来...

    Spring中文帮助文档

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

    Spring 3 Reference中文

    4.4.5.2 从自动装配中排除bean. 57 4.4.6 方法注入. 57 4.4.6.1 查找方法注入.. 58 4.4.6.2 任意方法的替代 59 4.5 Bean 的范围. 60 4.5.1 单例范围. 61 4.5.2 原型范围. 62 ...

    Spring in Action(第二版 中文高清版).part2

    B.2 单元测试Spring MVC控制器 B.2.1 模拟对象 B.2.2 断言ModelAndView的内容 B.3 使用Spring进行综合测试 B.3.1 测试装配后的对象 B.3.2 综合测试事务处理对象 B.3.3 测试数据库 B.3.4 使用Gienah Testing在...

    Spring in Action(第二版 中文高清版).part1

    B.2 单元测试Spring MVC控制器 B.2.1 模拟对象 B.2.2 断言ModelAndView的内容 B.3 使用Spring进行综合测试 B.3.1 测试装配后的对象 B.3.2 综合测试事务处理对象 B.3.3 测试数据库 B.3.4 使用Gienah Testing在...

    Spring.3.x企业应用开发实战(完整版).part2

    12.2 在Spring中使用Hibernate 12.2.1 配置SessionFactory 12.2.2 使用HibernateTemplate 12.2.3 处理LOB类型数据 12.2.4 添加Hibernate事件监听器 12.2.5 使用原生Hibernate API 12.2.6 使用注解配置 12.2.7 事务...

    spring chm文档

    6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. ...

    Spring API

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

    Spring in Action(第2版)中文版

    16.4.3在jsf页面中使用springbean 16.4.4在jsf中暴露应用程序环境 16.5spring中带有dwr的支持ajax的应用程序 16.5.1直接web远程控制 16.5.2访问spring管理的beandwr 16.6小结 附录a装配spring a.1下载spring ...

    Spring3.x企业应用开发实战(完整版) part1

    12.2 在Spring中使用Hibernate 12.2.1 配置SessionFactory 12.2.2 使用HibernateTemplate 12.2.3 处理LOB类型数据 12.2.4 添加Hibernate事件监听器 12.2.5 使用原生Hibernate API 12.2.6 使用注解配置 12.2.7 事务...

    Spring 2.0 开发参考手册

    6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. ...

    Spring攻略(第二版 中文高清版).part1

    6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2 解决方案 215 6.2.3 工作原理 215 6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4...

    Spring攻略(第二版 中文高清版).part2

    6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2 解决方案 215 6.2.3 工作原理 215 6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4...

    spring3.1中文参考文档

    spring3.1中文参考文档,南磊翻译,现在有4章,目录如下: 第一部分 Spring framework概述.......................................................................................................................

    JAVA程序开发大全---上半部分

    以及基于这些技术的商业化应用程序的开发技巧,在讲解过程中以目前最为流行的开发工具MyEclipse为载体,全面系统地介绍了如何在MyEclipse中开发基于Struts、Hibernate、Spring等主流框架的各种Java应用程序。...

    《MyEclipse 6 Java 开发中文教程》前10章

    10.5.2.5 用Spring 2.0 的@Transactional标注解决事务提交问题(最佳方案) 251 10.5.2.6 使用 HibernateTemplate 实现分页查询 254 10.6 小结 255 10.7 参考资料 255 10.7.1 MyEclipse生成的Spring+Hibernate无法...

    领域驱动设计与模式实战

    10.3.7 利用PicoContainer.NET进行自动装配 10.3.8 嵌套容器 10.3.9 服务定位器与依赖注入的比较 10.3.10 小结 10.4 面向方面编程 10.4.1 热门话题有哪些 10.4.2 AOP术语定义 10.4.3 .NET中的AOP 10.4.4 小结 10.5 ...

Global site tag (gtag.js) - Google Analytics