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的使用方法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,082评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,916评论 25 709
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,989评论 6 342
  • 人生短短几十年,不要给自己留下了什么遗憾,想笑就笑,想哭就哭,该爱的时候就去爱,无谓压抑自己。人生的苦闷有二,一是...
    控场王阅读 193评论 1 1
  • (1) 又一个闺蜜怀孕了,这已经是第三个了。自从放开二胎以来,我身边的闺蜜们,同学们跟约好了似的一个接一个的沦陷了...
    晴初雨阅读 236评论 0 1