📄 jdbctemplatetestsuite.java
字号:
/*
* Copyright 2002-2004 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.jdbc.core;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.easymock.MockControl;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.UncategorizedDataAccessException;
import org.springframework.jdbc.AbstractJdbcTests;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.SQLWarningException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
/**
* Mock object based tests for JdbcTemplate.
* @author Rod Johnson
*/
public class JdbcTemplateTestSuite extends AbstractJdbcTests {
public void testBeanProperties() throws Exception {
replay();
JdbcTemplate t = new JdbcTemplate(mockDataSource);
assertTrue("datasource ok", t.getDataSource() == mockDataSource);
assertTrue("ignores warnings by default", t.getIgnoreWarnings());
t.setIgnoreWarnings(false);
assertTrue("can set NOT to ignore warnings", !t.getIgnoreWarnings());
}
public void testCannotRunStaticSqlWithBindParameters() throws Exception {
final String sql = "UPDATE FOO SET NAME='tony' WHERE ID > ?";
replay();
JdbcTemplate t = new JdbcTemplate(mockDataSource);
try {
t.query(sql, new RowCountCallbackHandler());
fail("Should have objected to bind variables");
}
catch (InvalidDataAccessApiUsageException ex) {
// Ok
}
}
public void testUpdateCount() throws Exception {
final String sql =
"UPDATE INVOICE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
int idParam = 11111;
MockControl ctrlPreparedStatement =
MockControl.createControl(PreparedStatement.class);
PreparedStatement mockPreparedStatement =
(PreparedStatement) ctrlPreparedStatement.getMock();
mockPreparedStatement.setInt(1, idParam);
ctrlPreparedStatement.setVoidCallable();
mockPreparedStatement.executeUpdate();
ctrlPreparedStatement.setReturnValue(1);
mockPreparedStatement.getWarnings();
ctrlPreparedStatement.setReturnValue(null);
mockPreparedStatement.close();
ctrlPreparedStatement.setVoidCallable();
mockConnection.prepareStatement(sql);
ctrlConnection.setReturnValue(mockPreparedStatement);
ctrlPreparedStatement.replay();
replay();
Dispatcher d = new Dispatcher(idParam, sql);
JdbcTemplate template = new JdbcTemplate(mockDataSource);
int rowsAffected = template.update(d);
assertTrue("1 update affected 1 row", rowsAffected == 1);
/*
d = new Dispatcher(idParam);
rowsAffected = template.update(d);
assertTrue("bogus update affected 0 rows", rowsAffected == 0);
*/
ctrlPreparedStatement.verify();
}
public void testBogusUpdate() throws Exception {
final String sql =
"UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
final int idParam = 6666;
// It's because Integers aren't canonical
SQLException sex = new SQLException("bad update");
MockControl ctrlPreparedStatement =
MockControl.createControl(PreparedStatement.class);
PreparedStatement mockPreparedStatement =
(PreparedStatement) ctrlPreparedStatement.getMock();
mockPreparedStatement.setInt(1, idParam);
ctrlPreparedStatement.setVoidCallable();
mockPreparedStatement.executeUpdate();
ctrlPreparedStatement.setThrowable(sex);
mockPreparedStatement.close();
ctrlPreparedStatement.setVoidCallable();
mockConnection.prepareStatement(sql);
ctrlConnection.setReturnValue(mockPreparedStatement);
ctrlPreparedStatement.replay();
replay();
Dispatcher d = new Dispatcher(idParam, sql);
JdbcTemplate template = new JdbcTemplate(mockDataSource);
try {
template.update(d);
fail("Bogus update should throw exception");
}
catch (UncategorizedDataAccessException ex) {
// pass
assertTrue(
"Correct exception",
ex instanceof UncategorizedSQLException);
assertTrue("Root cause is correct", ex.getCause() == sex);
//assertTrue("no update occurred", !je.getDataWasUpdated());
}
ctrlPreparedStatement.verify();
}
public void testStringsWithStaticSql() throws Exception {
doTestStrings(new JdbcTemplateCallback() {
public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) {
template.query(sql, rch);
}
}, false, null);
}
public void testStringsWithEmptyPreparedStatementSetter() throws Exception {
doTestStrings(new JdbcTemplateCallback() {
public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) {
template.query(sql, (PreparedStatementSetter) null, rch);
}
}, true, null);
}
public void testStringsWithPreparedStatementSetter() throws Exception {
final Integer argument = new Integer(99);
doTestStrings(new JdbcTemplateCallback() {
public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) {
template.query(sql, new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
ps.setObject(1, argument);
}
}, rch);
}
}, true, argument);
}
public void testStringsWithEmptyPreparedStatementArgs() throws Exception {
doTestStrings(new JdbcTemplateCallback() {
public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) {
template.query(sql, (Object[]) null, rch);
}
}, true, null);
}
public void testStringsWithPreparedStatementArgs() throws Exception {
final Integer argument = new Integer(99);
doTestStrings(new JdbcTemplateCallback() {
public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) {
template.query(sql, new Object[] {argument}, rch);
}
}, true, argument);
}
protected void doTestStrings(JdbcTemplateCallback jdbcTemplateCallback,
boolean usePreparedStatement, Object argument) throws Exception {
String sql = "SELECT FORENAME FROM CUSTMR";
String[] results = { "rod", "gary", " portia" };
class StringHandler implements RowCallbackHandler {
private List l = new LinkedList();
public void processRow(ResultSet rs) throws SQLException {
l.add(rs.getString(1));
}
public String[] getStrings() {
return (String[]) l.toArray(new String[l.size()]);
}
}
MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
mockResultSet.next();
ctrlResultSet.setReturnValue(true);
mockResultSet.getString(1);
ctrlResultSet.setReturnValue(results[0]);
mockResultSet.next();
ctrlResultSet.setReturnValue(true);
mockResultSet.getString(1);
ctrlResultSet.setReturnValue(results[1]);
mockResultSet.next();
ctrlResultSet.setReturnValue(true);
mockResultSet.getString(1);
ctrlResultSet.setReturnValue(results[2]);
mockResultSet.next();
ctrlResultSet.setReturnValue(false);
mockResultSet.close();
ctrlResultSet.setVoidCallable();
MockControl ctrlStatement =
MockControl.createControl(PreparedStatement.class);
PreparedStatement mockStatement =
(PreparedStatement) ctrlStatement.getMock();
if (argument != null) {
mockStatement.setObject(1, argument);
}
if (usePreparedStatement) {
mockStatement.executeQuery();
}
else {
mockStatement.executeQuery(sql);
}
ctrlStatement.setReturnValue(mockResultSet);
mockStatement.getWarnings();
ctrlStatement.setReturnValue(null);
mockStatement.close();
ctrlStatement.setVoidCallable();
if (usePreparedStatement) {
mockConnection.prepareStatement(sql);
}
else {
mockConnection.createStatement();
}
ctrlConnection.setReturnValue(mockStatement);
ctrlResultSet.replay();
ctrlStatement.replay();
replay();
StringHandler sh = new StringHandler();
JdbcTemplate template = new JdbcTemplate(mockDataSource);
jdbcTemplateCallback.doInJdbcTemplate(template, sql, sh);
// Match
String[] forenames = sh.getStrings();
assertTrue("same length", forenames.length == results.length);
for (int i = 0; i < forenames.length; i++) {
assertTrue("Row " + i + " matches", forenames[i].equals(results[i]));
}
ctrlResultSet.verify();
ctrlStatement.verify();
}
public void testLeaveConnOpenOnRequest() throws Exception {
String sql = "SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3";
MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
ctrlResultSet = MockControl.createControl(ResultSet.class);
mockResultSet = (ResultSet) ctrlResultSet.getMock();
mockResultSet.next();
ctrlResultSet.setReturnValue(false);
mockResultSet.close();
ctrlResultSet.setVoidCallable();
MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class);
PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock();
ctrlStatement = MockControl.createControl(PreparedStatement.class);
mockStatement = (PreparedStatement) ctrlStatement.getMock();
mockStatement.executeQuery(sql);
ctrlStatement.setReturnValue(mockResultSet);
mockStatement.getWarnings();
ctrlStatement.setReturnValue(null);
mockStatement.close();
ctrlStatement.setVoidCallable();
mockConnection.isClosed();
ctrlConnection.setReturnValue(false, 2);
mockConnection.createStatement();
ctrlConnection.setReturnValue(mockStatement);
// if close is called entire test will fail
mockConnection.close();
ctrlConnection.setDefaultThrowable(new RuntimeException());
ctrlResultSet.replay();
ctrlStatement.replay();
replay();
SingleConnectionDataSource scf = new SingleConnectionDataSource(mockDataSource.getConnection(), false);
JdbcTemplate template2 = new JdbcTemplate(scf);
RowCountCallbackHandler rcch = new RowCountCallbackHandler();
template2.query(sql, rcch);
ctrlResultSet.verify();
ctrlStatement.verify();
}
public void testCloseConnOnRequest() throws Exception {
String sql = "SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3";
MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
mockResultSet.next();
ctrlResultSet.setReturnValue(false);
mockResultSet.close();
ctrlResultSet.setVoidCallable();
MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class);
PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock();
mockStatement.executeQuery(sql);
ctrlStatement.setReturnValue(mockResultSet);
mockStatement.getWarnings();
ctrlStatement.setReturnValue(null);
mockStatement.close();
ctrlStatement.setVoidCallable();
mockConnection.createStatement();
ctrlConnection.setReturnValue(mockStatement);
ctrlResultSet.replay();
ctrlStatement.replay();
replay();
JdbcTemplate template2 = new JdbcTemplate(mockDataSource);
RowCountCallbackHandler rcch = new RowCountCallbackHandler();
template2.query(sql, rcch);
ctrlResultSet.verify();
ctrlStatement.verify();
}
/**
* Test that we see a runtime exception come back.
*/
public void testExceptionComesBack() throws Exception {
final String sql = "SELECT ID FROM CUSTMR";
final RuntimeException rex = new RuntimeException("What I want to see");
MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
mockResultSet.next();
ctrlResultSet.setReturnValue(true);
mockResultSet.close();
ctrlResultSet.setVoidCallable();
MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class);
PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock();
mockStatement.executeQuery(sql);
ctrlStatement.setReturnValue(mockResultSet);
mockStatement.getWarnings();
ctrlStatement.setReturnValue(null);
mockStatement.close();
ctrlStatement.setVoidCallable();
mockConnection.createStatement();
ctrlConnection.setReturnValue(mockStatement);
ctrlResultSet.replay();
ctrlStatement.replay();
replay();
JdbcTemplate template = new JdbcTemplate(mockDataSource);
try {
template.query(sql, new RowCallbackHandler() {
public void processRow(java.sql.ResultSet rs)
throws java.sql.SQLException {
throw rex;
}
});
fail("Should have thrown exception");
}
catch (RuntimeException ex) {
assertTrue("Wanted same exception back, not " + ex, ex == rex);
}
}
/**
* Test update with static SQL.
*/
public void testSqlUpdate() throws Exception {
final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 4";
int rowsAffected = 33;
MockControl ctrlStatement = MockControl.createControl(Statement.class);
Statement mockStatement = (Statement) ctrlStatement.getMock();
mockStatement.executeUpdate(sql);
ctrlStatement.setReturnValue(rowsAffected);
mockStatement.getWarnings();
ctrlStatement.setReturnValue(null);
mockStatement.close();
ctrlStatement.setVoidCallable();
mockConnection.createStatement();
ctrlConnection.setReturnValue(mockStatement);
ctrlStatement.replay();
replay();
JdbcTemplate template = new JdbcTemplate(mockDataSource);
int actualRowsAffected = template.update(sql);
assertTrue(
"Actual rows affected is correct",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -