I am using Kotlin 1.7.10 and Mockk 1.12.4 and I have a factory method in the following spring bean class:
@Service
class DataSynchronizationManagerFactoryService(
private val platformTransactionManager: PlatformTransactionManager
) {
fun <D : DataDto, E : DbEntity, R : DataSynchronizableRepository<E>> constructDataSynchronisationManager(
processedEntityType: Class<E>,
repository: R,
dataLoaderAndTransformer: DataLoaderAndTransformer<D, E>
): DataSynchronisationManager<D, E, R> {
return DataSynchronisationManager<D, E, R>(
processedEntityType,
repository,
dataLoaderAndTransformer,
TransactionTemplate(platformTransactionManager)
)
}
}
where D
, E
and R
are the following respective interfaces:
public interface DataDto {
String getSystemId();
}
public interface DbEntity {
String getSystemId();
}
@NoRepositoryBean
public interface DataSynchronizableRepository<T extends DbEntity> extends
JpaRepository<T, String>,
BatchPersistableRepository<T> {
void deleteBySystemIdIn(Collection<String> systemIds);
}
I am attempting to mock call to the constructDataSynchronisationManager
method using Mockk:
every {
dataSynchronizationManagerFactoryServiceMock
.constructDataSynchronisationManager<DataDto, DbEntity, DataRepository>(
any(),
any(),
any(),
)
} returns dataSynchronisationManagerMock
and I am getting the following error:
java.lang.InstantiationError: com.andrew.DataRepository
at jdk.internal.reflect.GeneratedSerializationConstructorAccessor7.newInstance(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
at io.mockk.proxy.jvm.ObjenesisInstantiator.instanceViaObjenesis(ObjenesisInstantiator.kt:75)
at io.mockk.proxy.jvm.ObjenesisInstantiator.instance(ObjenesisInstantiator.kt:42)
at io.mockk.impl.instantiation.JvmInstantiator$instantiate$2.invoke(JvmInstantiator.kt:16)
at io.mockk.impl.instantiation.AbstractInstantiator.instantiateViaInstanceFactoryRegistry(AbstractInstantiator.kt:17)
at io.mockk.impl.instantiation.JvmInstantiator.instantiate(JvmInstantiator.kt:15)
at io.mockk.impl.recording.states.RecordingState$matcher$signatureValue$1$1.invoke(RecordingState.kt:49)
at io.mockk.impl.instantiation.JvmAnyValueGenerator$anyValue$2.invoke(JvmAnyValueGenerator.kt:35)
at io.mockk.impl.instantiation.AnyValueGenerator.anyValue(AnyValueGenerator.kt:34)
at io.mockk.impl.instantiation.JvmAnyValueGenerator.anyValue(JvmAnyValueGenerator.kt:31)
at io.mockk.impl.recording.states.RecordingState$matcher$signatureValue$1.invoke(RecordingState.kt:48)
at io.mockk.impl.recording.JvmSignatureValueGenerator.signatureValue(JvmSignatureValueGenerator.kt:20)
at io.mockk.impl.recording.states.RecordingState.matcher(RecordingState.kt:47)
at io.mockk.impl.recording.CommonCallRecorder.matcher(CommonCallRecorder.kt:52)
If I create an actual implementation of the DataRepository:
class DataRepositoryImpl: DataRepository<...> {
// provide empty implementation of all methods
}
and then use the DataRepositoryImpl
in the every
block to simulate the behavior, the mock goes through, but it is suboptimal because it does not represent the actual code.
Is there a way to mock the call to the generic method so that the InstantiationError
does not happen?