每个mock对象都需要手工创建么?答案当然是否定的我们有FactoryBean通过在配置文件中指定bean的定义让spring来替我们创建mock对象如下是针对Foo类的定义
<bean id=mockFoo class=orgeasymockEasyMock factorymethod=createMock>
<constructorarg index= value=Foo/>
</bean>
< /constructorarg>与此同时Spring TestContext框架提供了 @ContextConfiguration annotation 允许开发人员手工指定 Spring 配置文件所在的位置这样开发过程中如果开发人员遵循比较好的配置文件组织结构可以维护一套只用于测试的对象关系配置里面只维护测试用到的 mock 对象以及测试中用到的对 mock 对象有依赖关系的对象在产品代码中则使用另一套配置文件配置真实的业务对象
JUnit 之后Test 类上可以通过 @RunWith 注解指定测试用例的 TestRunner Spring TestContext框架提供了扩展于 orgjunitinternalrunnersJUnitClassRunner 的 SpringJUnitClassRunner它负责总装 Spring TestContext 测试框架并将其统一到 JUnit 框架中这样你可以把 Test 类上的关于 Spring Test 类的继承关系去掉并且使用 JUnit 之后引入的 annotation 去掉其他任何 JUnit 需要的约定和方法继承让 Test 类更加 POJO
Test 类也是纯正 的 java 对象自然也可以通过 Spring 来管理依赖关系在 Test 类的成员变量上加上 @Autowired 声明使用 SpringJUnitClassRunner 运行 Test CaseSpring 会很聪明地帮助我们摆平 Test 依赖的对象然后再运行已经合法的 Test Case只要你在用于测试的配置文件里面定义了完整的依赖关系一如其他正常对象
<bean id=
Helloword
class=
Helloworld
autowire=
byType
/>
这样经过上面三点变化例子代码变成了这样
import static orgeasymockEasyMock*;
@RunWith(SpringJUnitClassRunnerclass)
@ContextConfiguration(testcontextxml)
public void HelloworldTest {
@Autowired
private Foo foo;
@Autowired
private Bar bar;
@Autowired
private Helloworld helloworld;
@Before
public void before() {
reset(foo bar);
}
@After
public void after() {
verify(foo bar);
}
@Test
public void shouldSayHello() {
//set expectations about foo/bar
replay(foo bar);
helloworldsayHello();
//assert verification
}
//
}
[] [] []