带有 Spring JdbcTemplate 的 SimpleJdbcCall 的 Mockito
Mockito for SimpleJdbcCall with Spring JdbcTemplate
我尝试了多种方法在我的 Junit 测试用例中执行存储过程来测试输出值,但不幸的是没有任何效果。
我的测试用例:
public class DataTest {
@Mock
private static DataSource ds;
@InjectMocks
private DataDaoImpl dataDao = new DataDaoImpl();
@Mock
private static JdbcTemplate jdbcTemplate;
@Mock
private static SimpleJdbcCall viewProc;
@Before
public void setUp() throws IOException, InterruptedException {
MockitoAnnotations.initMocks(this);
MockMvcBuilders.standaloneSetup(dataDao).build();
}
@BeforeClass
public static void init() throws Exception {
viewProc = new SimpleJdbcCall(ds).withSchemaName("schema")
.withProcedureName("viewProc").withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlParameter("param1", Types.VARCHAR))
.declareParameters(new SqlParameter("param2", Types.VARCHAR))
.returningResultSet("dataModules", Mockito.anyObject());
jdbcTemplate = new JdbcTemplate(ds);
}
@Test
public void findDataModules() throws Exception {
String param1 = "abc";
List<DataObj> md = new ArrayList<DataObj>();
int size = 3;
SqlParameterSource in = new MapSqlParameterSource().addValue("param1", "abc").addValue("param2",
"123");
Map map = viewProc.execute(in);
md = (List<DataObj>) map.get("data");
assertTrue("Expected Data ", md.size() >= size);
}
}
我的主class:
@Repository
public class DataDaoImpl implements DataDao {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Resource(name = "db")
private DataSource db;
private SimpleJdbcCall viewProc;
private JdbcTemplate jdbcTemplate;
/**
* Initialization of Stored Procs and JDBC Template
*
* @throws Exception
*/
@PostConstruct
public void init() throws Exception {
viewProc = new SimpleJdbcCall(db).withSchemaName("schema")
.withProcedureName("viewProc").withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlParameter("param1", Types.VARCHAR))
.declareParameters(new SqlParameter("param2", Types.VARCHAR))
.returningResultSet("data", new ViewDataRowMapper());
jdbcTemplate = new JdbcTemplate(db);
}
@Override
public List<Data> findUniqueDataModules(String p1, String p2) throws Exception {
List<DataObj> dataModules = new ArrayList<DataObj>();
try {
SqlParameterSource in = new MapSqlParameterSource().addValue("param1", p1).addValue("param2",
p2);
Map map = viewUniqueDataModulesByLicense.execute(in);
dataModules = (List<DataObj>) map.get("data");
} catch (Exception e) {
//Hnadel Exception
}
return dataModules;
}
}
上面的代码给出了异常,表示需要数据源。
我尝试了 Mockito、powerMockito,但它返回了空地图。模拟也不例外。
我可以接受任何可以通过我的测试用例的解决方案。
修改命名。
尽管我讨厌在测试中使用反射,但我相信它可以帮助您解决您的问题。在这里,初始化后,我将字段 viewProc
设置为一个模拟对象,您可以在测试中使用它。 @PostConstruct
是Spring相关注解,所以初始化时不会调用。
class DataDaoImplTest {
private DataDaoImpl dataDao;
@Mock
private DataSource dataSource;
@Mock
private SimpleJdbcCall jdbcCall;
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
this.dataDao = new DataDaoImpl(dataSource);
ReflectionTestUtils.setField(this.dataDao, "viewProc", jdbcCall);
}
@Test
void findUniqueDataModules() throws Exception {
// given:
Map<String, Object> map = new HashMap<>();
map.put("data", Arrays.asList(new DataDaoImpl.DataObj(), new DataDaoImpl.DataObj()));
// mocks:
when(jdbcCall.execute(any(SqlParameterSource.class))).thenReturn(map);
// when:
List<DataDaoImpl.DataObj> uniqueDataModules = this.dataDao.findUniqueDataModules("a", "b");
// then:
assertEquals(2, uniqueDataModules.size());
}
}
另一种解决方案是针对测试数据库(如 H2)测试该方法。但它不会是单元测试。
我尝试了多种方法在我的 Junit 测试用例中执行存储过程来测试输出值,但不幸的是没有任何效果。 我的测试用例:
public class DataTest {
@Mock
private static DataSource ds;
@InjectMocks
private DataDaoImpl dataDao = new DataDaoImpl();
@Mock
private static JdbcTemplate jdbcTemplate;
@Mock
private static SimpleJdbcCall viewProc;
@Before
public void setUp() throws IOException, InterruptedException {
MockitoAnnotations.initMocks(this);
MockMvcBuilders.standaloneSetup(dataDao).build();
}
@BeforeClass
public static void init() throws Exception {
viewProc = new SimpleJdbcCall(ds).withSchemaName("schema")
.withProcedureName("viewProc").withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlParameter("param1", Types.VARCHAR))
.declareParameters(new SqlParameter("param2", Types.VARCHAR))
.returningResultSet("dataModules", Mockito.anyObject());
jdbcTemplate = new JdbcTemplate(ds);
}
@Test
public void findDataModules() throws Exception {
String param1 = "abc";
List<DataObj> md = new ArrayList<DataObj>();
int size = 3;
SqlParameterSource in = new MapSqlParameterSource().addValue("param1", "abc").addValue("param2",
"123");
Map map = viewProc.execute(in);
md = (List<DataObj>) map.get("data");
assertTrue("Expected Data ", md.size() >= size);
}
}
我的主class:
@Repository
public class DataDaoImpl implements DataDao {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Resource(name = "db")
private DataSource db;
private SimpleJdbcCall viewProc;
private JdbcTemplate jdbcTemplate;
/**
* Initialization of Stored Procs and JDBC Template
*
* @throws Exception
*/
@PostConstruct
public void init() throws Exception {
viewProc = new SimpleJdbcCall(db).withSchemaName("schema")
.withProcedureName("viewProc").withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlParameter("param1", Types.VARCHAR))
.declareParameters(new SqlParameter("param2", Types.VARCHAR))
.returningResultSet("data", new ViewDataRowMapper());
jdbcTemplate = new JdbcTemplate(db);
}
@Override
public List<Data> findUniqueDataModules(String p1, String p2) throws Exception {
List<DataObj> dataModules = new ArrayList<DataObj>();
try {
SqlParameterSource in = new MapSqlParameterSource().addValue("param1", p1).addValue("param2",
p2);
Map map = viewUniqueDataModulesByLicense.execute(in);
dataModules = (List<DataObj>) map.get("data");
} catch (Exception e) {
//Hnadel Exception
}
return dataModules;
}
}
上面的代码给出了异常,表示需要数据源。 我尝试了 Mockito、powerMockito,但它返回了空地图。模拟也不例外。 我可以接受任何可以通过我的测试用例的解决方案。 修改命名。
尽管我讨厌在测试中使用反射,但我相信它可以帮助您解决您的问题。在这里,初始化后,我将字段 viewProc
设置为一个模拟对象,您可以在测试中使用它。 @PostConstruct
是Spring相关注解,所以初始化时不会调用。
class DataDaoImplTest {
private DataDaoImpl dataDao;
@Mock
private DataSource dataSource;
@Mock
private SimpleJdbcCall jdbcCall;
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
this.dataDao = new DataDaoImpl(dataSource);
ReflectionTestUtils.setField(this.dataDao, "viewProc", jdbcCall);
}
@Test
void findUniqueDataModules() throws Exception {
// given:
Map<String, Object> map = new HashMap<>();
map.put("data", Arrays.asList(new DataDaoImpl.DataObj(), new DataDaoImpl.DataObj()));
// mocks:
when(jdbcCall.execute(any(SqlParameterSource.class))).thenReturn(map);
// when:
List<DataDaoImpl.DataObj> uniqueDataModules = this.dataDao.findUniqueDataModules("a", "b");
// then:
assertEquals(2, uniqueDataModules.size());
}
}
另一种解决方案是针对测试数据库(如 H2)测试该方法。但它不会是单元测试。