架构探险-第二章:为Web应用添加业务功能(8)-优化Junit单元测试

一,前言

上一节补全了CustomerService的增删改查方法,执行Junit测试了方法的正确性 
不过这里存在一个问题:
    当执行完Junit测试,deleteCustomerTest的测试方法使id=1的数据被删除 
    导致下次执行Junit时测试数据就不存在了

这一节将对Junit做进一步优化,以便适合于正式项目的开发和测试流程

二,解决方法

拷贝一个测试数据库,与开发库分离(正式环境中还会有正式库)
提供测试数据库的配置文件,Junit使用测试库进行测试
为单元测试准备测试数据,将要执行的sql存放在.sql文件中
在执行测试前执行测试准备数据,进行测试

三,创建测试数据库,准备测试数据和配置文件

1,创建测试数据库

使用Navicat创建新的数据库:demo_test
复制domo数据库中customer表到demo_test数据库

2,准备测试数据

在test/resources/sql目录下创建customer_init.sql存放测试数据
TRUNCATE customer;
INSERT INTO `customer` VALUES ('1', 'customer1', 'Brave', '13600000000', '[email protected]', null);
INSERT INTO `customer` VALUES ('2', 'customer2', 'BraveWang', '13600000000', '[email protected]', null);
先执行TRUNCATE语句清空所有数据,再执行INSERT语句插入相关数据

默认IDEA不会在test下创建resource目录,需要手工创建
创建resource目录后,右键单击此目录,
选择Mark Directory As/Resources Root将其设置为Maven的测试资源目录

注意:main/java, main/resources, test/java, test/resources这四个目录为classpath的根目录
当运行单元测试时,遵循"就近原则",即优先从test/java, test/resources加载类或读取文件

3,创建测试数据库配置文件

在test/resources目录下创建测试数据库配置文件config.properties

config.properties:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/demo_test
jdbc.username=root
jdbc.password=123

四,优化Junit单元测试类

调用每个@Test方法前都会调用@Before方法为测试设置初始化
之前的单元测试类中,预留了一个init方法,正式用来做数据库初始化

CustomerServiceTest:

    @Before
    public void init() throws Exception {
        String file = "sql/customer_init.sql";
        //获取当前线程上下文中的ClassLoader,通过"sql/customer_init.sql"获取一个InputStream对象
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(file);
        //通过输入流创建BufferReader
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        // 循环读取每一行,并调用DatabaseHelper.executeUpdate执行每一条sql
        String sql;
        while( (sql=reader.readLine()) != null){
            DatabaseHelper.executeUpdate(sql);
        }
    }
在init方法中,获取当前线程上下文中的ClassLoader,
通过"sql/customer_init.sql"获取一个InputStream输入流对象
通过输入流创建BufferReader,循环读取每一行,
并调用DatabaseHelper.executeUpdate执行每一条sql

最后,将init方法的逻辑封装到DatabaseHelper中便于复用

DatabaseHelper:

    /**
     * 执行SQL文件
     */
    public static void executeSqlFile(String filePath) {
        //获取当前线程上下文中的ClassLoader,通过"sql/customer_init.sql"获取一个InputStream对象
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
        //通过输入流创建BufferReader
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        // 循环读取每一行,并调用DatabaseHelper.executeUpdate执行每一条sql

        try {
            String sql;
            while( (sql=reader.readLine()) != null){
                executeUpdate(sql);
            }
        } catch (IOException e) {
            LOGGER.error("execute sql file failure", e);
            throw new RuntimeException(e);
        }
    }

然后在CustomerServiceTest.init方法中调用:

CustomerServiceTest:

@Before
public void init() throws Exception {
    String file = "sql/customer_init.sql";
    DatabaseHelper.executeSqlFile(file);
}

执行全部测试方法:

这里写图片描述


四,结尾

本节为Junit单元测试创建了测试数据库,数据库配置文件,初始化sql,
封装了读取并执行sql的方法,在Junit初始化时执行Sql
优化并完善了Junit单元测试的环境

至此,对于服务层的优化就完成了
下一节开始对控制器层做优化,获取数据放入请求属性并将数据显示在jsp页面上

猜你喜欢

转载自blog.csdn.net/abap_brave/article/details/80522778