diff --git a/README.rst b/README.rst index 9140d39..3892d56 100644 --- a/README.rst +++ b/README.rst @@ -173,6 +173,8 @@ Changelog - Enrich exceptions with message from java SQLExceptions + - Fix typo LONGNARCHAR vs LONGVARCHAR (thanks @datdo for reporting #4) + - 0.1.5 - 2015-03-02 - Add version number to module. diff --git a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java new file mode 100644 index 0000000..f62e7ec --- /dev/null +++ b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java @@ -0,0 +1,49 @@ +package org.jaydebeapi.mockdriver; + +import java.lang.reflect.Field; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Types; +import org.mockito.Mockito; + +public abstract class MockConnection implements Connection { + + ResultSet mockResultSet; + + public final void mockType(String sqlTypesName) throws SQLException { + PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class); + Mockito.when(mockPreparedStatement.execute()).thenReturn(true); + mockResultSet = Mockito.mock(ResultSet.class, "ResultSet(for type " + sqlTypesName + ")"); + Mockito.when(mockPreparedStatement.getResultSet()).thenReturn(mockResultSet); + Mockito.when(mockResultSet.next()).thenReturn(true); + ResultSetMetaData mockMetaData = Mockito.mock(ResultSetMetaData.class); + Mockito.when(mockResultSet.getMetaData()).thenReturn(mockMetaData); + Mockito.when(mockMetaData.getColumnCount()).thenReturn(1); + int sqlTypeCode = extractTypeCodeForName(sqlTypesName); + Mockito.when(mockMetaData.getColumnType(1)).thenReturn(sqlTypeCode); + Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); + } + + private int extractTypeCodeForName(String sqlTypesName) { + try { + Field field = Types.class.getField(sqlTypesName); + return field.getInt(null); + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException("Type " + sqlTypesName + " not found in Types class.", e); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public final ResultSet verifyResultSet() { + return Mockito.verify(mockResultSet); + } + +} diff --git a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockDriver.java b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockDriver.java index 25cf9ea..888ed80 100644 --- a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockDriver.java +++ b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockDriver.java @@ -4,7 +4,6 @@ import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.DriverPropertyInfo; -import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.Properties; @@ -28,10 +27,7 @@ public class MockDriver implements Driver { if (!acceptsURL(url)) { return null; } - Connection mockConnection = Mockito.mock(Connection.class); - PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class); - Mockito.when(mockConnection.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); - return mockConnection; + return Mockito.mock(MockConnection.class); } @Override diff --git a/src/jaydebeapi/dbapi2.py b/src/jaydebeapi/dbapi2.py index 067b868..2b05711 100644 --- a/src/jaydebeapi/dbapi2.py +++ b/src/jaydebeapi/dbapi2.py @@ -218,7 +218,7 @@ class DBAPITypeObject(object): STRING = DBAPITypeObject('CHAR', 'NCHAR', 'NVARCHAR', 'VARCHAR', 'OTHER') -TEXT = DBAPITypeObject('CLOB', 'LONGNVARCHAR', 'LONGNARCHAR', 'NCLOB', 'SQLXML') +TEXT = DBAPITypeObject('CLOB', 'LONGVARCHAR', 'LONGNVARCHAR', 'NCLOB', 'SQLXML') BINARY = DBAPITypeObject('BINARY', 'BLOB', 'LONGVARBINARY', 'VARBINARY') diff --git a/test/test_mock.py b/test/test_mock.py index 3b69637..2112f01 100644 --- a/test/test_mock.py +++ b/test/test_mock.py @@ -7,12 +7,12 @@ # it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # JayDeBeApi is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. -# +# # You should have received a copy of the GNU Lesser General Public # License along with JayDeBeApi. If not, see # . @@ -24,11 +24,25 @@ import unittest2 as unittest class MockTest(unittest.TestCase): def setUp(self): - self.conn = jaydebeapi.connect('org.jaydebeapi.mockdriver.MockDriver', 'jdbc:jaydebeapi://dummyurl') + self.conn = jaydebeapi.connect('org.jaydebeapi.mockdriver.MockDriver', + 'jdbc:jaydebeapi://dummyurl') def tearDown(self): self.conn.close() - def test_execute(self): - cursor = self.conn.cursor() - cursor.execute("dummy stmt") + def test_all_db_api_type_objects_have_valid_mapping(self): + extra_type_mappings = { 'DATE': 'getDate', + 'TIME': 'getTime', + 'TIMESTAMP': 'getTimestamp' } + for db_api_type in jaydebeapi.__dict__.values(): + if isinstance(db_api_type, jaydebeapi.DBAPITypeObject): + for jsql_type_name in db_api_type.values: + self.conn.jconn.mockType(jsql_type_name) + cursor = self.conn.cursor() + cursor.execute("dummy stmt") + cursor.fetchone() + verify = self.conn.jconn.verifyResultSet() + verify_get = getattr(verify, + extra_type_mappings.get(jsql_type_name, + 'getObject')) + verify_get(1)