zoukankan      html  css  js  c++  java
  • Spring+SpringMVC+MyBatis+easyUI整合优化篇(四)单元测试实例

    前言

    前一篇文章《Spring+SpringMVC+MyBatis+easyUI整合优化篇(三)代码测试》讲了不为和不能两个状态,针对不为,只能自己调整心态了,而对于不能,本文会结合一些实例进行讲解,应该可以使得你掌握单元测试的方法。篇幅所限,所以先写三个类型的测试实例,首先是自己平时写着玩儿的测试类,然后分别是针对数据层和业务层的测试,代码都已经上传到github上了。
    我的github地址

    简单的测试

    我们可能常常会碰到这种事情,需要实现一个功能的时候,忽然想不起来该用什么方法了,或者忽然忘记一个方法该怎么用了,这个时候我可能会查一下API然后写一个简单的测试方法,并没有明确的要去测试什么功能,只是简单的验证一个函数的用法,或者自己实在不确定一个方法该怎么用了,用这种方式加深一下印象。

         // 得到MD5加密的内容
        @Test
        public void md5Test() {
            System.out.println(MD5Util.MD5Encode("ssm-maven-secret", "UTF-8"));
         //83d8d99f45f62461cc7b7ee76b448cb0
        }
    
    
         // 通过substring()获取文件名
        @Test
        public void subStringTest() {
            //通过substring()获取文件名
            String url = "https://s.doubanio.com/f/shire/5522dd1f5b742d1e1394a17f44d590646b63871d/pics/book-default-medium.gif";
            url = url.substring(url.lastIndexOf("/") + 1);
            System.out.println(url);
            //book-default-medium.gif
        }
    

    这个只是自己的个人习惯,记忆力有时候真的差。

    数据层单元测试

    针对书籍模块的测试类,讲解在代码中:

    @RunWith(SpringJUnit4ClassRunner.class) //指定测试用例的运行器 这里是指定了Junit4
    @ContextConfiguration("classpath:applicationContext.xml")//装配Spring
    public class BookDaoTest {
        //自动注入,需要将BookDao纳入到Spring容器的管理下,不然会报错
        @Autowired
        private BookDao bookDao;
    
        @Test
        public void getBookByIdTest() {
            Book book1 = bookDao.getBookById("1");
            Assert.assertEquals(book1, null);//判断两个参数是否相同,返回true的话则测试通过,不然控制台会亮红灯。
            Book book2 = bookDao.getBookById("1002");
            Assert.assertEquals(book2.getTitle(), "材料成型概论");
            // Assert.assertEquals(book2.getTitle(), "我随便写一个");
            //写了三个断言,可以分别进行测试,也可以根据上面三个断言自己编写测试。
        }
    
    }
    

    针对书籍模块的测试类,讲解也都在代码中:

    
    @RunWith(SpringJUnit4ClassRunner.class) //指定测试用例的运行器 这里是指定了Junit4
    @ContextConfiguration("classpath:applicationContext.xml")
    
    @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
    //默认回滚,即此类中的方法即使执行成功,数据也并不会真正的修改,方法执行后会回滚。
    //因为对数据库的增删改都会回滚,因此便于测试用例的循环利用
    //前面书籍模块的测试由于只有查询方法所以没有加这个注解。
    //如果想看到数据库中的数据随着测试而发生变化可以去掉这个注解。
    public class UserDaoTest {
        @Autowired
        //自动注入,需要将BookDao纳入到Spring容器的管理下
        private UserDao userDao;
    
        @Test
        public void loginTest() {
            User user = new User();
            user.setUserName("admin");
            user.setPassword("123456");
            //断言此姓名和密码的用户为空
            //密码并没有加密,所以登录失败,返回的用户对象为空。
            Assert.assertEquals(userDao.login(user), null);
            User user2 = new User();
            user2.setUserName("admin");
            user2.setPassword(MD5Util.MD5Encode("123456", "UTF-8"));
            //断言此姓名和密码的用户可以登录成功,且用户id为2
            Assert.assertTrue(userDao.login(user2).getId() == 2);
            //执行下面这个断言则会报错。
            //Assert.assertTrue(userDao.login(user2).getId() == 3);
    
        }
    
        @Test
        public void findUsersTest() {
            //断言此时返回的用户列表数大于0
            Assert.assertTrue(userDao.findUsers(null).size() > 0);
            //断言此时返回的用户列表数等于3,数字你可以随便写,用户数可能是错的,如果报错你会看到控制台一片红色
            Assert.assertTrue(userDao.findUsers(null).size() == 3);
        }
    
        @Test
        public void getTotalUserTest() {
            Assert.assertTrue(userDao.getTotalUser(null) > 0);
            Assert.assertTrue(userDao.getTotalUser(null) == 3);
        }
    
    //使用update、insert、delete方法时,会得到一个返回值,这个返回值说明了执行一条sql语句后,表中有多少条记录被影响了。
    //比如用update修改一条记录,如果修改成功了,返回值为1,返回0则是修改失败。
    
        @Test
        public void updateUserTest() {
            User user = new User();
            user.setId(51);
            user.setPassword("1221");
            //大于0的意思是成功修改了一条记录,即修改成功,如果updateUser()方法返回值等于0,即修改失败
            Assert.assertTrue(userDao.updateUser(user) > 0);
            User user2 = new User();
            user2.setId(1000);
            user2.setPassword("234y9823y89hhao");
            Assert.assertTrue(userDao.updateUser(user2) > 0);
        }
    
        @Test
        public void addUserTest() {
            User user = new User();
            user.setUserName("测试用户");
            user.setPassword(MD5Util.MD5Encode("testuser", "UTF-8"));
            //大于0的意思是影响了数据库中的一条记录,即添加成功
            Assert.assertTrue(userDao.addUser(user) > 0);
        }
    
        @Test
        public void deleteUserTest() {
            Assert.assertTrue(userDao.deleteUser(51) > 0);
        }
    
    }
    

    大家可以将代码pull到本地进行测试,并根据上面几个方法写一下自己的测试用例。

    service的单元测试

    其实service层的单元测试和dao层并没有太多区别,唯一的不同可能就是service层方法中可以执行多条sql语句,而dao层的方法只能执行一条sql语句,因此这个例子更侧重于讲一下事务问题

    配置文件:

        <!-- 配置事务通知属性 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <!-- 定义事务传播属性 -->
            <tx:attributes>
            <!--事务切面中insert开头的方法会被纳入事务管理中-->
                <tx:method name="insert*" propagation="REQUIRED"/>
                <tx:method name="update*" propagation="REQUIRED"/>
                <tx:method name="upd*" propagation="REQUIRED"/>
            </tx:attributes>
            ......
        </tx:advice>
    
        <!-- 配置事务切面 -->
        <aop:config>
            <aop:pointcut id="serviceOperation"
                          expression="(execution(* com.ssm.maven.core.service.*.*(..)))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/>
        </aop:config>
    

    业务方法:

    //通过Spring的配置文件,此方法已经纳入到其事务管理下
    //发生异常时会触发事务回滚,数据不会被更改
    public int insertStore(Store store) {
            int level = Integer.valueOf(store.getLevel());
            for (int i = 1; i < level; i++) {
                store.setLevel(i + "");
                storeDao.insertStore(store);
            }
            store.setLevel(level + "");
            int result = storeDao.insertStore(store);
            int i = 10 / 0;
            //发生异常,操作回滚.
            //可以试着将上面一条语句注释掉再运行测试用例,看看有什么区别。
            return result;
        }
    

    测试用例:

    @RunWith(SpringJUnit4ClassRunner.class) //指定测试用例的运行器 这里是指定了Junit4
    @ContextConfiguration("classpath:applicationContext.xml")
    //@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
    //不添加此设置,测试service层的事务管理
    //service层与dao层的测试时相同的,不同之处,在于service层多数都会在配置文件中配置spring的事务管理
    public class StoreServiceTest {
        @Autowired
        private StoreService storeService;
    
        @Test
        public void insertStoreTest() {
            Store store = new Store();
            store.setLevel("5");
            store.setNumber("TEST");
            storeService.insertStore(store);
            int i = 10 / 0;
            //这里发生异常是不会回滚的,因为此方法并没有被纳入事务管理中
        }
    
    }
    

    这个例子可能有些简单,一般业务层方法都会较为复杂,如下:

    function(){
    -A-
    
    SQL1
    
    -B-
    
    SQL2
    
    -C-
    
    SQL3
    
    -D-
    }
    

    那么执行此方法时,无论在A处、B处、C处、D处发生异常,都会触发事务回滚,关于Spring的事务管理事务传播属性,想了解的可以自己去查询一下。

    总结

    本篇主要讲了数据层和业务层的测试,下一篇主要会讲一下controller控制层的测试,睡觉啦...

  • 相关阅读:
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1056:点和正方形的关系
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1056:点和正方形的关系
    信息学奥赛一本通(C++)在线评测系统——基础(三)数据结构 —— 1339:【例34】求后序遍历
    信息学奥赛一本通(C++)在线评测系统——基础(三)数据结构 —— 1339:【例34】求后序遍历
    信息学奥赛一本通(C++)在线评测系统——基础(三)数据结构 —— 1339:【例34】求后序遍历
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1055:判断闰年
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1055:判断闰年
    python 连接sqlserver
    python 连接sqlserver
    python中__name__的意义以及作用
  • 原文地址:https://www.cnblogs.com/han-1034683568/p/6649077.html
Copyright © 2011-2022 走看看