3
Unit Test
Calvin Xiao edited this page 2014-01-18 08:03:57 -08:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

单元测试是针对某个类的测试,又分为将依赖类完全以Mock形式隔离的纯单元测试,以及使用真实的依赖类的非纯粹单元测试两类。

##1. Mock对象(Mockito 与 PowerMock) 内容较多,详见Mock。

##2. AssertJ写的Assert语句 内容较多,详见AssertJ。

##3. Spring ApplicationContext Testcase

Spring提供了自己的Listener和Runner, 并提供了两个基类

1. AbstractJUnit4SpringContextTests, 使用了这些Runner和Listener,子类只需要定义自己的applicationContext.xml文件路径,即可以用annotation将需要的Bean注入到用例里,或者使用它的applicationContext成员变量动态获取任意Bean。

@ContextConfiguration(locations = { "/applicationContext-test.xml" })
public class BeanValidatorsTest extends AbstractJUnit4SpringContextTests

它最有特色的一点是在整个测试期间,缓存SpringContext,以在用例里标注的context文件路径为key, 比如两个都使用"applicationContext-test.xml"的用例,会重用同一个context,减少了重复创建的时间。

但如果还有一个用例标注为"applicationContext-test.xml,applicationContext-cxf.xml", 则会创建出一个新的Context,两个Context同时并存,如果两个Context都需要占用端口,都使用嵌入式内存数据库,就会有悲剧发生了.....这个时候, Spring提供一个Class和方法级别标注@DirtiesContext,会在方法或类完成后,执行该Context的close,并把它从缓存中抹掉。 必须在每个有冲突的TestClass上不厌其烦的加上这个标签。

2. AbstractTransactionalJUnit4SpringContextTests, 在AbstractJUnit4SpringContextTests的基础上,多用了一个TransactionalTestExecutionListener, 增加了事务管理的能力,默认Rollback全部事务。另外提供了countRowsInTable, deleteFromTables和executeSqlScript三个有用函数。 如果Context里有多数据源时请看Transaction章节。

###SpringSide的扩展

1. SpringContextTestCase, 继承于AbstractJUnit4SpringContextTests,但名字短多了,还设定了@ActiveProfiles("test")

2. SpringTransactionalTestCase, 继承于AbstractTransactionalJUnit4SpringContextTests, 同样名字短多了,且设定了@ActiveProfiles("test"),还多保存了一个dataSource变量以作后用。

##4. 测试Private方法/变量 首先可以review一下设计,问一下为什么要单独测试private函数。然后:

  1. 通过SpringSide的Reflections或者spring的ReflectionTestUtils暴力反射调用。
  2. 将方法开放成public或protected或无修饰符(测试用例通常与测试类同一package),并加上Guava的@ReflectionTestUtils或其他自定义annotation表明只是为了测试才开放的修饰。