自定义加载器
在我们的测试基类中,我们使用了Spring-test提供的加载器
@RunWith(SpringJUnit4ClassRunner.class)
为了实现上文说的效果,我们需要自定义自己的加载器
public class MyJUnit4ClassRunner extends SpringJUnit4ClassRunner{
public MyJUnit4ClassRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
}
查看一下SpringJUnit4ClassRunner的源码,他告诉我们应该怎么书写我们的加载器。下面是我们书写的加载器
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
public class MyJUnit4ClassRunner extends SpringJUnit4ClassRunner{
private Class<?> clazz;
public MyJUnit4ClassRunner(Class<?> clazz) throws InitializationError {
super(clazz);
this.clazz = clazz;
}
// 拦截 BeforeClass 事件
@Override
protected Statement withBeforeClasses(Statement statement) {
final Statement junitStatement = super.withBeforeClasses(statement);
return new Statement() {
@Override
public void evaluate() throws Throwable {
System.out.println("Before Class: " + clazz.getName());
junitStatement.evaluate();
}
};
}
// 拦截每一个方法的 Before 事件
@Override
protected Statement withBefores(final FrameworkMethod frameworkMethod, Object testInstance, Statement statement) {
final Statement junitStatement = super.withAfters(frameworkMethod, testInstance, statement);
return new Statement() {
@Override
public void evaluate() throws Throwable {
System.out.println("测试类: " + clazz.getName() + "--测试方法: " + frameworkMethod.getName() + " 开始执行!");
junitStatement.evaluate();
}
};
}
// 截获测试类的 AfterClass 事件
@Override
protected Statement withAfterClasses(Statement statement) {
final Statement junitStatement = super.withAfterClasses(statement);
return new Statement() {
@Override
public void evaluate() throws Throwable {
junitStatement.evaluate();
System.out.println("After Class: " + clazz.getName());
}
};
}
// 截获每一个测试方法的 after 事件
@Override
protected Statement withAfters(final FrameworkMethod frameworkMethod, Object testInstance, Statement statement) {
final Statement junitStatement = super.withAfters(frameworkMethod, testInstance, statement);
return new Statement() {
@Override
public void evaluate() throws Throwable {
System.out.println("测试类: " + clazz.getName() + "--测试方法: " + frameworkMethod.getName() + " 执行结束!");
junitStatement.evaluate();
}
};
}
}
使用加载器
修改我们的测试基类即可
//@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(MyJUnit4ClassRunner.class)
进行测试,会有如下的输出
测试类: com.yun.spring.UserAssignServiceTest--测试方法: insert 执行结束!
测试类: com.yun.spring.UserAssignServiceTest--测试方法: insert 开始执行!
自定义监听器
public class DBUnitTestExecutionListener implements TestExecutionListener {
@Override
public void beforeTestClass(TestContext testContext) throws Exception {
}
@Override
public void prepareTestInstance(TestContext testContext) throws Exception {
}
/**
* 在执行测试操作之前
*/
@Override
public void beforeTestMethod(TestContext testContext) throws Exception {
System.out.println(this.getClass().getName() + "--" + testContext.getTestMethod().getName() + " 测试开始");
}
@Override
public void afterTestMethod(TestContext testContext) throws Exception {
System.out.println(this.getClass().getName() + "--" + testContext.getTestMethod().getName() + " 测试结束");
}
@Override
public void afterTestClass(TestContext testContext) throws Exception {
}
}
使用监听器
修改上文中的BaseJunit4Test类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
"classpath:test-hcm-context.xml",
"classpath:test-hcm-jpa.xml",
"classpath:test-hcm-servlet.xml",
"classpath:test-hcm-memcache.xml"})
// 这个非常关键,如果不加入这个注解配置,事务控制就会完全失效!
@Transactional
// 这里的事务关联到配置文件中的事务控制器(transactionManager = "transactionManager"),同时
// 指定自动回滚(defaultRollback = true)。这样做操作的数据才不会污染数据库!
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@TestExecutionListeners( {
DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DBUnitTestExecutionListener.class })
public class BaseJunit4Test {
}
@TestExecutionListeners中的参数书写我们自定义的监听器来完成某些操作
TestRule的使用
Rule是一个用于测试单元类中定义一个域的标注。虽然叫Rule,但是仍然起拦截器/Interceptor的作用——即在运行测试的前后添加一些有用的代码。这里没有使用,有兴趣自行查看一下文档。
预告
下一步我们将介绍hamcrest的使用方法