Spring JdbcTemplate Junit 测试 - ResultSetExtractor/RowMapper

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

1、RowMapper Mockito 测试

(1)创建实体类 User

java 复制代码
@Data
public class User {

    private Integer id;

    private String name;

    private String applicant;

    private String address;

    private Boolean flag;
}

(2)JdbcTemplate 业务代码

java 复制代码
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);
    }
}

(3)Junit 测试

java 复制代码
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());
    }
}
2、ResultSetExtractor Mockito 测试

(1)创建 User 实体

java 复制代码
import lombok.Data;

@Data
public class User {

    private Integer id;

    private String name;

    private String applicant;

    private String address;

    private Boolean flag;
}

(2)JdbcTemplate 业务代码

java 复制代码
 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);
    }

(3)Junit 测试

java 复制代码
 @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());
    }
相关推荐
wang_book3 小时前
Gitlab学习(007 gitlab项目操作)
java·运维·git·学习·spring·gitlab
一个诺诺前行的后端程序员5 小时前
springcloud微服务实战<1>
spring·spring cloud·微服务
Tatakai258 小时前
Mybatis Plus分页查询返回total为0问题
java·spring·bug·mybatis
掐指一算乀缺钱9 小时前
SpringBoot 数据库表结构文档生成
java·数据库·spring boot·后端·spring
bug菌¹10 小时前
滚雪球学SpringCloud[4.2讲]: Zuul:Netflix API Gateway详解
spring·spring cloud·gateway
小哇66610 小时前
spring-TransactionTemplate 编程式事务
数据库·spring
测试界柠檬11 小时前
接口测试到底测试什么?
自动化测试·软件测试·功能测试·程序人生·职场和发展·单元测试·压力测试
ChinaRainbowSea12 小时前
十三,Spring Boot 中注入 Servlet,Filter,Listener
java·spring boot·spring·servlet·web
小游鱼KF12 小时前
Spring学习前置知识
java·学习·spring
阿乾之铭13 小时前
spring MVC 拦截器
java·spring·mvc