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;
}
(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 {@AutowiredJdbcTemplate jdbcTemplate;public List<User> getUsers(String sql, String name, String address) {return jdbcTemplate.query(sql, new RowMapper<User>() {@Overridepublic 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 测试
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 {@MockJdbcTemplate jdbcTemplate;@InjectMocksInsertGroup insertGroup;@Beforepublic void init() {MockitoAnnotations.openMocks(this);}@Testpublic 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 RowassertFirstUser(userList.get(0));// Assert Second RowassertSecondUser(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 实体
import lombok.Data;@Data
public class User {private Integer id;private String name;private String applicant;private String address;private Boolean flag;
}
(2)JdbcTemplate 业务代码
public List<User> getUsers2(String sql, String name, String address) {return jdbcTemplate.query(sql, new ResultSetExtractor<List<User>>() {@Overridepublic 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 测试
@Testpublic 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());}