📄 storedproceduretests.java
字号:
/*
* Copyright 2002-2005 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.object;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
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.jdbc.AbstractJdbcTests;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ParameterMapper;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.SqlReturnResultSet;
import org.springframework.jdbc.core.support.AbstractSqlTypeValue;
import org.springframework.jdbc.datasource.ConnectionHolder;
import org.springframework.jdbc.support.SQLExceptionTranslator;
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* @author Thomas Risberg
* @author Trevor Cook
* @author Rod Johnson
*/
public class StoredProcedureTests extends AbstractJdbcTests {
private MockControl ctrlCallable;
private CallableStatement mockCallable;
protected void setUp() throws Exception {
super.setUp();
ctrlCallable = MockControl.createControl(CallableStatement.class);
mockCallable = (CallableStatement) ctrlCallable.getMock();
}
protected void tearDown() throws Exception {
super.tearDown();
if (shouldVerify()) {
ctrlCallable.verify();
}
}
protected void replay() {
super.replay();
ctrlCallable.replay();
}
public void testNoSuchStoredProcedure() throws Exception {
SQLException sex =
new SQLException(
"Syntax error or access violation exception",
"42000");
mockCallable.execute();
ctrlCallable.setThrowable(sex);
mockCallable.close();
ctrlCallable.setVoidCallable();
mockConnection.prepareCall(
"{call " + NoSuchStoredProcedure.SQL + "()}");
ctrlConnection.setReturnValue(mockCallable);
replay();
NoSuchStoredProcedure sproc = new NoSuchStoredProcedure(mockDataSource);
try {
sproc.execute();
fail("Shouldn't succeed in running stored procedure which doesn't exist");
} catch (BadSqlGrammarException ex) {
// OK
}
}
private void testAddInvoice(final int amount, final int custid)
throws Exception {
AddInvoice adder = new AddInvoice(mockDataSource);
int id = adder.execute(amount, custid);
assertEquals(4, id);
}
public void testAddInvoices() throws Exception {
mockCallable.setObject(1, new Integer(1106), Types.INTEGER);
ctrlCallable.setVoidCallable();
mockCallable.setObject(2, new Integer(3), Types.INTEGER);
ctrlCallable.setVoidCallable();
mockCallable.registerOutParameter(3, Types.INTEGER);
ctrlCallable.setVoidCallable();
mockCallable.execute();
ctrlCallable.setReturnValue(false);
mockCallable.getUpdateCount();
ctrlCallable.setReturnValue(-1);
mockCallable.getObject(3);
ctrlCallable.setReturnValue(new Integer(4));
mockCallable.getWarnings();
ctrlCallable.setReturnValue(null);
mockCallable.close();
ctrlCallable.setVoidCallable();
mockConnection.prepareCall("{call " + AddInvoice.SQL + "(?, ?, ?)}");
ctrlConnection.setReturnValue(mockCallable);
replay();
testAddInvoice(1106, 3);
}
public void testAddInvoicesWithinTransaction() throws Exception {
mockCallable.setObject(1, new Integer(1106), Types.INTEGER);
ctrlCallable.setVoidCallable();
mockCallable.setObject(2, new Integer(3), Types.INTEGER);
ctrlCallable.setVoidCallable();
mockCallable.registerOutParameter(3, Types.INTEGER);
ctrlCallable.setVoidCallable();
mockCallable.execute();
ctrlCallable.setReturnValue(false);
mockCallable.getUpdateCount();
ctrlCallable.setReturnValue(-1);
mockCallable.getObject(3);
ctrlCallable.setReturnValue(new Integer(4));
mockCallable.getWarnings();
ctrlCallable.setReturnValue(null);
mockCallable.close();
ctrlCallable.setVoidCallable();
mockConnection.prepareCall("{call " + AddInvoice.SQL + "(?, ?, ?)}");
ctrlConnection.setReturnValue(mockCallable);
replay();
TransactionSynchronizationManager.bindResource(
mockDataSource,
new ConnectionHolder(mockConnection));
try {
testAddInvoice(1106, 3);
}
finally {
TransactionSynchronizationManager.unbindResource(mockDataSource);
}
}
/**
* Confirm no connection was used to get metadata.
* Does not use superclass replay mechanism.
* @throws Exception
*/
public void testStoredProcedureConfiguredViaJdbcTemplateWithCustomExceptionTranslator() throws Exception {
mockCallable.setObject(1, new Integer(11), Types.INTEGER);
ctrlCallable.setVoidCallable(1);
mockCallable.registerOutParameter(2, Types.INTEGER);
ctrlCallable.setVoidCallable(1);
mockCallable.execute();
ctrlCallable.setReturnValue(false, 1);
mockCallable.getUpdateCount();
ctrlCallable.setReturnValue(-1);
mockCallable.getObject(2);
ctrlCallable.setReturnValue(new Integer(5), 1);
mockCallable.getWarnings();
ctrlCallable.setReturnValue(null);
mockCallable.close();
ctrlCallable.setVoidCallable(1);
// Must call this here as we're not using setUp()/tearDown() mechanism
ctrlCallable.replay();
ctrlConnection = MockControl.createControl(Connection.class);
mockConnection = (Connection) ctrlConnection.getMock();
mockConnection.prepareCall("{call " + StoredProcedureConfiguredViaJdbcTemplate.SQL + "(?, ?)}");
ctrlConnection.setReturnValue(mockCallable, 1);
mockConnection.close();
ctrlConnection.setVoidCallable(1);
ctrlConnection.replay();
MockControl dsControl = MockControl.createControl(DataSource.class);
DataSource localDs = (DataSource) dsControl.getMock();
localDs.getConnection();
dsControl.setReturnValue(mockConnection, 1);
dsControl.replay();
class TestJdbcTemplate extends JdbcTemplate {
int calls;
public Map call(CallableStatementCreator csc, List declaredParameters) throws DataAccessException {
calls++;
return super.call(csc, declaredParameters);
}
}
TestJdbcTemplate t = new TestJdbcTemplate();
t.setDataSource(localDs);
// Will fail without the following, because we're not able to get a connection from the
// DataSource here if we need to to create an ExceptionTranslator
t.setExceptionTranslator(new SQLStateSQLExceptionTranslator());
StoredProcedureConfiguredViaJdbcTemplate sp = new StoredProcedureConfiguredViaJdbcTemplate(t);
assertEquals(sp.execute(11), 5);
assertEquals(1, t.calls);
dsControl.verify();
ctrlCallable.verify();
ctrlConnection.verify();
}
/**
* Confirm our JdbcTemplate is used
* @throws Exception
*/
public void testStoredProcedureConfiguredViaJdbcTemplate() throws Exception {
mockCallable.setObject(1, new Integer(1106), Types.INTEGER);
ctrlCallable.setVoidCallable();
mockCallable.registerOutParameter(2, Types.INTEGER);
ctrlCallable.setVoidCallable();
mockCallable.execute();
ctrlCallable.setReturnValue(false);
mockCallable.getUpdateCount();
ctrlCallable.setReturnValue(-1);
mockCallable.getObject(2);
ctrlCallable.setReturnValue(new Integer(4));
mockCallable.getWarnings();
ctrlCallable.setReturnValue(null);
mockCallable.close();
ctrlCallable.setVoidCallable();
mockConnection.prepareCall("{call " + StoredProcedureConfiguredViaJdbcTemplate.SQL + "(?, ?)}");
ctrlConnection.setReturnValue(mockCallable);
replay();
JdbcTemplate t = new JdbcTemplate();
t.setDataSource(mockDataSource);
StoredProcedureConfiguredViaJdbcTemplate sp = new StoredProcedureConfiguredViaJdbcTemplate(t);
assertEquals(sp.execute(1106), 4);
}
public void testNullArg() throws Exception {
MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
mockResultSet.next();
ctrlResultSet.setReturnValue(true);
mockCallable.setNull(1, Types.VARCHAR);
ctrlCallable.setVoidCallable();
mockCallable.execute();
ctrlCallable.setReturnValue(false);
mockCallable.getUpdateCount();
ctrlCallable.setReturnValue(-1);
mockCallable.getWarnings();
ctrlCallable.setReturnValue(null);
mockCallable.close();
ctrlCallable.setVoidCallable();
mockConnection.prepareCall("{call " + NullArg.SQL + "(?)}");
ctrlConnection.setReturnValue(mockCallable);
replay();
ctrlResultSet.replay();
NullArg na = new NullArg(mockDataSource);
na.execute((String) null);
}
public void testUnnamedParameter() throws Exception {
replay();
try {
UnnamedParameterStoredProcedure unp =
new UnnamedParameterStoredProcedure(mockDataSource);
fail("Shouldn't succeed in creating stored procedure with unnamed parameter");
} catch (InvalidDataAccessApiUsageException idaauex) {
// OK
}
}
public void testMissingParameter() throws Exception {
replay();
try {
MissingParameterStoredProcedure mp =
new MissingParameterStoredProcedure(mockDataSource);
mp.execute();
fail("Shouldn't succeed in running stored procedure with missing required parameter");
} catch (InvalidDataAccessApiUsageException idaauex) {
// OK
}
}
public void testStoredProcedureExceptionTranslator() throws Exception {
SQLException sex =
new SQLException(
"Syntax error or access violation exception",
"42000");
mockCallable.execute();
ctrlCallable.setThrowable(sex);
mockCallable.close();
ctrlCallable.setVoidCallable();
mockConnection.prepareCall(
"{call " + StoredProcedureExceptionTranslator.SQL + "()}");
ctrlConnection.setReturnValue(mockCallable);
replay();
StoredProcedureExceptionTranslator sproc =
new StoredProcedureExceptionTranslator(mockDataSource);
try {
sproc.execute();
fail("Custom exception should be thrown");
} catch (CustomDataException ex) {
// OK
}
}
public void testStoredProcedureWithResultSet() throws Exception {
MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
mockResultSet.next();
ctrlResultSet.setReturnValue(true);
mockResultSet.next();
ctrlResultSet.setReturnValue(true);
mockResultSet.next();
ctrlResultSet.setReturnValue(false);
mockCallable.getWarnings();
ctrlCallable.setReturnValue(null);
mockResultSet.close();
ctrlResultSet.setVoidCallable();
mockCallable.execute();
ctrlCallable.setReturnValue(true);
mockCallable.getUpdateCount();
ctrlCallable.setReturnValue(-1);
mockCallable.getResultSet();
ctrlCallable.setReturnValue(mockResultSet);
mockCallable.getMoreResults();
ctrlCallable.setReturnValue(false);
mockCallable.getUpdateCount();
ctrlCallable.setReturnValue(-1);
mockCallable.close();
ctrlCallable.setVoidCallable();
mockConnection.prepareCall(
"{call " + StoredProcedureWithResultSet.SQL + "()}");
ctrlConnection.setReturnValue(mockCallable);
replay();
ctrlResultSet.replay();
StoredProcedureWithResultSet sproc =
new StoredProcedureWithResultSet(mockDataSource);
sproc.execute();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -