• Spring JdbcTemplate Junit 测试 - ResultSetExtractor/RowMapper


    Spring JdbcTemplate Junit 测试覆盖率 - 以 ResultSetExtractor / RowMapper 为例

    1、RowMapper Mockito 测试

    (1)创建实体类 User

    @Data
    public class User {
    
        private Integer id;
    
        private String name;
    
        private String applicant;
    
        private String address;
    
        private Boolean flag;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    (2)JdbcTemplate 业务代码

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.RowMapper;
    import org.springframework.stereotype.Repository;
    
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.List;
    
    @Repository
    public class InsertGroup {
    
        @Autowired
        JdbcTemplate jdbcTemplate;
    
        public List<User> getUsers(String sql, String name, String address) {
    
            return jdbcTemplate.query(sql, new RowMapper<User>() {
                @Override
                public User mapRow(ResultSet rs, int rowNum) throws SQLException {
    
                    User user = new User();
                    user.setId(rs.getInt("ID"));
                    user.setName(rs.getString("Name"));
                    user.setApplicant(rs.getString("Applicant"));
                    user.setAddress(rs.getString("Address"));
                    user.setFlag(rs.getBoolean("Flag"));
                    return user;
                }
            }, name, address);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    (3)Junit 测试

    package com.example.dao;
    
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.*;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.RowMapper;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import java.sql.ResultSet;
    import java.util.ArrayList;
    import java.util.List;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    public class InsertGroupTest {
    
        @Mock
        JdbcTemplate jdbcTemplate;
    
        @InjectMocks
        InsertGroup insertGroup;
    
        @Before
        public void init() {
            MockitoAnnotations.openMocks(this);
        }
    
    
        @Test
        public void test() {
    
          /**
             * 需要注意的是:invocation.getArgument(1)
             * jdbcTemplate.query() 中 Mock 的参数索引是以0开始的,RowMapper 是第二个元素,因此索引是 1,如果是第三个位置,那么索引是 2,即 invocation.getArgument(2)
             * 同时需要注意的是,jdbcTemplate 中 query 的方法有很多,但是传的参数是不同的,因此 Mock 的参数数量要根据自己实际用到的 query 参数为准
             */
            Mockito.when(jdbcTemplate.query(
                            ArgumentMatchers.anyString(), ArgumentMatchers.any(RowMapper.class), ArgumentMatchers.any()))
                    .thenAnswer((invocation) -> {
    
                        RowMapper<User> rowMapper = (RowMapper<User>) invocation.getArgument(1);
                        ResultSet rs = Mockito.mock(ResultSet.class);
    
                        // Mock ResultSet to return one rows.
                        // Mockito.when(rs.getInt(ArgumentMatchers.eq("ID"))).thenReturn(506);
    
                        // Mock ResultSet to return two rows.
                        Mockito.when(rs.getInt(ArgumentMatchers.eq("ID")))
                                .thenReturn(412, 300);
                        Mockito.when(rs.getString(ArgumentMatchers.eq("Name")))
                                .thenReturn("刘亦菲", "刘诗诗");
                        Mockito.when(rs.getBoolean(ArgumentMatchers.eq("Flag")))
                                .thenReturn(true, false);
    
                        List<User> users = new ArrayList<>();
                        users.add(rowMapper.mapRow(rs, 0));
                        users.add(rowMapper.mapRow(rs, 1));
    
                        return users;
                    });
    
            List<User> userList = insertGroup.getUsers("sql", "1", "2");
    
            // Assert First Row
            assertFirstUser(userList.get(0));
    
            // Assert Second Row
            assertSecondUser(userList.get(1));
        }
    
        public void assertFirstUser(User user) {
            Assert.assertEquals(Integer.valueOf(412), user.getId());
            Assert.assertEquals("刘亦菲", user.getName());
            Assert.assertTrue(user.getFlag());
        }
    
        public void assertSecondUser(User user) {
            Assert.assertEquals(Integer.valueOf(300), user.getId());
            Assert.assertEquals("刘诗诗", user.getName());
            Assert.assertFalse(user.getFlag());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    2、ResultSetExtractor Mockito 测试

    (1)创建 User 实体

    import lombok.Data;
    
    @Data
    public class User {
    
        private Integer id;
    
        private String name;
    
        private String applicant;
    
        private String address;
    
        private Boolean flag;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    (2)JdbcTemplate 业务代码

     public List<User> getUsers2(String sql, String name, String address) {
    
            return jdbcTemplate.query(sql, new ResultSetExtractor<List<User>>() {
                @Override
                public List<User> extractData(ResultSet rs) throws SQLException, DataAccessException {
                    List<User> userList = new ArrayList<>();
                    while (rs.next()) {
                        User user = new User();
                        user.setId(rs.getInt("ID"));
                        user.setName(rs.getString("Name"));
                        user.setApplicant(rs.getString("Applicant"));
                        user.setAddress(rs.getString("Address"));
                        user.setFlag(rs.getBoolean("Flag"));
                        userList.add(user);
                    }
                    return userList;
                }
            }, name, address);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    (3)Junit 测试

     @Test
        public void test2() {
            Mockito.when(jdbcTemplate.query(
                            ArgumentMatchers.anyString(), ArgumentMatchers.any(ResultSetExtractor.class), ArgumentMatchers.any()))
                    .thenAnswer((invocation) -> {
                        ResultSetExtractor<List<User>> resultSetExtractor =
                                (ResultSetExtractor<List<User>>) invocation.getArgument(1);
    
                        ResultSet rs = Mockito.mock(ResultSet.class);
    
                        // two times it returns true and third time returns false.
                        Mockito.when(rs.next()).thenReturn(true, true, false);
    
                        // Mock ResultSet to return two rows.
                        Mockito.when(rs.getInt(ArgumentMatchers.eq("ID")))
                                .thenReturn(412, 300);
                        Mockito.when(rs.getString(ArgumentMatchers.eq("Name")))
                                .thenReturn("刘亦菲", "刘诗诗");
                        Mockito.when(rs.getBoolean(ArgumentMatchers.eq("Flag")))
                                .thenReturn(true, false);
    
                        return resultSetExtractor.extractData(rs);
                    });
    
            List<User> users = insertGroup.getUsers2("sql", "1", "2");
    
            Assert.assertEquals(Integer.valueOf(412), users.get(0).getId());
            Assert.assertEquals("刘亦菲", users.get(0).getName());
            Assert.assertTrue(users.get(0).getFlag());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    Java学习--多线程
    1024程序员节特色海报两张
    基于卷积神经网络(CNN)的深度迁移学习在声发射(AE)监测螺栓连接状况的应用
    testng-xslt使用详细教程
    一文了解函数设计的最佳实践
    Java8和Java9新特性
    【AIGC专题】Stable Diffusion 从入门到企业级实战0403
    软件工程综合实践课程第二周作业(简单工厂模式实验)
    Redis_01_Redis安装与使用
    K8s: 在Pod中将configmap数据注入容器
  • 原文地址:https://blog.csdn.net/m0_58680865/article/details/134429114