JaveEE测试:第二步-JUNIT自定义

自定义加载器

在我们的测试基类中,我们使用了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的使用方法

你可能感兴趣的:(JaveEE测试:第二步-JUNIT自定义)