junit - Mockito: Getting ClassCastException from a constructor call with a mock as argument -
i want unit test method signature as
public oracle.sql.array methoda(java.sql.connection connection)
the connection object mocked using
mockito.mock(connection.class)
and passed methoda while testing it.
oracle.sql.array has constructor
new array(oracle.sql.arraydescriptor, connection, object)
the methoda has logic obtaining arraydescriptor. has logic providing third argument constructor provides array of objects
i mocking these 2 set of logics , passing mocked arraydescriptor object , mocked object array. these mocking work correctly.
so constructor invocation like
new array(arraydescriptormock, connectionmock, objectmock)
this constructor call throws exception when executed part of test
java.lang.classcastexception:$java.sql.connection$$enhancerbymockitowithcglib$$2427854e cannot cast oracle.jdbc.oracleconnection
i have made many attempts mock constructor call avoiding error. however, each proved futile. documenting mocking code constructor
attempt1
powermockito.whennew(array.class).withparametertypes(arraydescriptor.class, connection.class, object.class) .witharguments(any(arraydescriptor.class), any(connection.class), any(object[].class)) .thenreturn(expectedarray);
attempt2
powermockito.whennew(array.class).witharguments(arraydescriptormock,connectionmock,objectarraymock).thenreturn(expectedarray);
legend: arraydescriptormock: mock of arraydescriptor
connectionmock: mock of connection
objectarraymock: mock of object array mocking code as
object[] structarraymock = new object[2]; struct obj1 = mock(struct.class); struct obj2 = mock(struct.class); structarraymock[0] = obj1; structarraymock[1] = obj2;
notes: method under test has following code did not mock
object[] objarray = new object[2];
i using powermockito, mockito , testng. however, believe issue has nothing testng, therefore junit tag should fine.
kindly advise why classcastexception coming , how avoid it?
edit believe mockito suppose intercept constructor call. meaning should not allow execution of real constructor. suppose return mock object of array class. why not happen? why attempting casting ?
the beginning of answer in straightforward message of exception.
... cannot cast oracle.jdbc.oracleconnection
the code shows oracle.sql.array
object oracle driver don't accept object
(and mocks) implementing jdbc interface such java.sql.connection
. somehow expected connector architecture, jdbc included follows jca principles.
why expected because objects jca implementation need know / interact own objects internally. java.sql.connection
interface minimal usable contract must exists clients spi (jdbc there).
so given fact , oracle.sql.array
oracle driver type, expected object needs internal oracle.sql.connection
behave normally. mocking oracle.jdbc.oracleconnection
won't array
using coupled type in more ways expected, , lead hellish fixture.
ussually we, mockists, : "don't mock types don't own. that's not mocking oracle.sql.connection
. in test don't see why test code written else , jdbc driver if 1 driver developer.
if need test daos or repositories uses array
, writing integration tests
(with real oracle) better fit.
to answer intention, go it. here's why :
actually tested code involves proprietary types @ point. , these types come driver must connect real database provide connection work with. don't see easy way unit test,
- maybe there's hidden types in oracle driver can help, that's maybe , introduce fragility , difficulty refactor if later team decides change database.
- or can use mock of
array
, break purpose specific test
and must add first reason reason why write integration tests when system needs connect another. cover application boundaries, including persistence. call business api of repositories (which daos business oriented api) , job whatever datastore behind. oracle or others change implementation of driver, remove types, etc. , don't have rewrite tests, actual implementation.
Comments
Post a Comment