Why is Mockk failing and calling real method when doing coVerify(exactly = 0) - kotlin

I have recently started programming in Kotlin and for writing unit test I am using Mockk library.
I am stuck at a particular point where Mockk fails while mocking a generic class.
I have a class called KafkaService which looks like this and this is also the class which I am trying to mock
#Service
class KafkaService<P : Any>(private val kafkaTemplate: KafkaTemplate<String, String>) {
suspend fun send(topic: String, data: P, headers: MutableMap<String, String?>, key: String? = null): SendResult<String, String>? {
val message: Message<P> = MessageBuilder
.withPayload(data)
.copyHeaders(headers)
.setHeader(KafkaHeaders.TOPIC, topic)
.setHeader(KafkaHeaders.KEY, key)
.build()
return kafkaTemplate.send(message).join()
}
}
There is another service VendorService which I am trying to test and looks somewhat like this
#Service
class VendorService(
private val kafkaService: KafkaService<String>
) : Service {
override suspend fun handle(flowToken: String, request: request) {
.
.
// Some code which returns before kafkaService.send is called
kafkaService.send(topic, payload, kafkaHeaders)
.
.
}
Since I am testing a scenario for function handle of VendorService, in which handle function returns before calling kafkaService.send(topic, payload, kafkaHeaders)
I am doing this
#ExtendWith(MockKExtension::class)
class Test {
#MockK
lateinit var kafkaService: KafkaService<String>
#BeforeEach
fun init() {
vendorService = VendorService(kafkaService)
}
#Test
fun `test handle - should return before calling kafkaService`() = runBlocking {
.
.
vendorService.handle(uuid, request)
coVerify(exactly = 0) { kafkaService.send(any(), any(), any()) }
.
.
}
}
My test fails at step where I do coVerify, the test goes inside the send function of kafkaService as if it were a real object although I have mocked it and fails with a null pointer exception because KafkaService takes KafkaTemplate<String, String> as dependency but since I am mocking KafkaService, I am not providing the dependency i.e. the dependency is null.
Am I not right in thinking that a mocked object should not call its real method, also I receive some warning logs from Mockk library which might be helpful, also in the end of the stack trace we can see the null pointer exception despite KafkaService being mocked
WARNING: Failed to transform class service/KafkaService
java.lang.IllegalArgumentException: Cannot resolve P from static java.lang.Object service.KafkaService.send$suspendImpl(?)
at net.bytebuddy.description.TypeVariableSource$AbstractBase.findExpectedVariable(TypeVariableSource.java:174)
at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$Substitutor$ForAttachment.onTypeVariable(TypeDescription.java:2062)
at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$Substitutor$ForAttachment.onTypeVariable(TypeDescription.java:1973)
at net.bytebuddy.description.type.TypeDescription$Generic$OfTypeVariable$Symbolic.accept(TypeDescription.java:5931)
at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$Substitutor.onParameterizedType(TypeDescription.java:1908)
at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$Substitutor$ForAttachment.onParameterizedType(TypeDescription.java:1973)
at net.bytebuddy.description.type.TypeDescription$Generic$OfParameterizedType.accept(TypeDescription.java:5134)
at net.bytebuddy.description.method.ParameterDescription$Latent.getType(ParameterDescription.java:805)
at net.bytebuddy.description.method.ParameterList$AbstractBase.asTypeList(ParameterList.java:107)
at net.bytebuddy.description.method.MethodDescription$AbstractBase.hashCode(MethodDescription.java:936)
at java.base/java.util.HashMap.hash(HashMap.java:338)
at java.base/java.util.HashMap.put(HashMap.java:610)
at java.base/java.util.HashSet.add(HashSet.java:221)
at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:336)
at java.base/java.util.HashSet.<init>(HashSet.java:121)
at net.bytebuddy.dynamic.scaffold.MethodRegistry$Default.prepare(MethodRegistry.java:457)
at net.bytebuddy.dynamic.scaffold.inline.RedefinitionDynamicTypeBuilder.toTypeWriter(RedefinitionDynamicTypeBuilder.java:203)
at net.bytebuddy.dynamic.scaffold.inline.AbstractInliningDynamicTypeBuilder.toTypeWriter(AbstractInliningDynamicTypeBuilder.java:122)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$UsingTypeWriter.make(DynamicType.java:4050)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3734)
at io.mockk.proxy.jvm.transformation.InliningClassTransformer.transform(InliningClassTransformer.kt:78)
at java.instrument/java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:244)
at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:541)
at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:169)
at io.mockk.proxy.jvm.transformation.JvmInlineInstrumentation.retransform(JvmInlineInstrumentation.kt:28)
at io.mockk.proxy.common.transformation.RetransformInlineInstrumentation$execute$1.invoke(RetransformInlineInstrumentation.kt:19)
at io.mockk.proxy.common.transformation.RetransformInlineInstrumentation$execute$1.invoke(RetransformInlineInstrumentation.kt:16)
at io.mockk.proxy.common.transformation.ClassTransformationSpecMap.applyTransformation(ClassTransformationSpecMap.kt:41)
at io.mockk.proxy.common.transformation.RetransformInlineInstrumentation.execute(RetransformInlineInstrumentation.kt:16)
at io.mockk.proxy.jvm.ProxyMaker.inline(ProxyMaker.kt:88)
at io.mockk.proxy.jvm.ProxyMaker.proxy(ProxyMaker.kt:30)
at io.mockk.impl.instantiation.JvmMockFactory.newProxy(JvmMockFactory.kt:34)
at io.mockk.impl.instantiation.AbstractMockFactory.newProxy$default(AbstractMockFactory.kt:24)
at io.mockk.impl.instantiation.AbstractMockFactory.mockk(AbstractMockFactory.kt:59)
at io.mockk.impl.annotations.JvmMockInitializer.assignMockK(JvmMockInitializer.kt:163)
at io.mockk.impl.annotations.JvmMockInitializer.initMock(JvmMockInitializer.kt:41)
at io.mockk.impl.annotations.JvmMockInitializer.initAnnotatedMocks(JvmMockInitializer.kt:24)
at io.mockk.junit5.MockKExtension.postProcessTestInstance(MockKExtension.kt:181)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:377)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:382)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:377)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:376)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:289)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:288)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278)
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277)
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:105)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:104)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:68)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Cannot invoke "org.springframework.kafka.core.KafkaTemplate.send(org.springframework.messaging.Message)" because "$this.kafkaTemplate" is null
java.lang.NullPointerException: Cannot invoke "org.springframework.kafka.core.KafkaTemplate.send(org.springframework.messaging.Message)" because "$this.kafkaTemplate" is null
at service.KafkaService.send$suspendImpl(KafkaService.kt:20)
at service.KafkaService.send(KafkaService.kt)
Here are Mockk dependencies which I am using
testImplementation("com.ninja-squad:springmockk:4.0.0")
testImplementation("io.mockk:mockk:1.13.3")
I am working on a Springboot 3.0.1 project which requires JDK 17.
Please help.
Update
I removed the Parameter P from KafkaService and after that the mockk test started running, also changing the class level parameter P to function level parameter of send worked fine i.e.
suspend fun <P> send(topic: String, data: P, headers: MutableMap<String, String?>, key: String? = null): SendResult<String, String>?

Related

Mock Bigquery function in kotlin unit test

I am develop an unit test, which involved (com.google.api.services.bigquery.Bigquery). I mock the object with mockk #SpyK. But the every{} block report error when unit test start. Detail as follow
the dependency is:
"com.google.apis:google-api-services-bigquery:v2-rev20220326-1.32.1"
The exception is throw in setUp() function
Code
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
#ExtendWith(MockKExtension::class, SpringExtension::class)
#EnableConfigurationProperties(ConfidentialTags::class)
#PropertySource(value = ["classpath:application.yml"], factory = YamlPropertySourceFactory::class)
class ResourceAccessServiceTest {
private val mockGoogleCredential = MockGoogleCredential.Builder().build()
#SpyK
private var olderBigQuery: Bigquery = Bigquery.Builder(
MockGoogleCredential.newMockHttpTransportWithSampleTokenResponse(),
mockGoogleCredential.jsonFactory,
mockGoogleCredential
).build()
#InjectMockKs
private lateinit var resourceAccessService: ResourceAccessService
#BeforeAll
fun setUp() {
//error reported here
every { olderBigQuery.RowAccessPolicies().list(any(), any(), any()).execute() } returns mockk() {
every { rowAccessPolicies } returns listOf()
}
}
#Test
fun queryRowAccessExistedPrincipals() {
val list = resourceAccessService.queryRowAccessExistedPrincipals(
TableId.of("proj", "ds", "tbl"),
RowFilter("region", listOf("hk"))
)
assert(list.isEmpty())
}
}
error log
java.net.MalformedURLException: no protocol: projects/2af774bb308513d5/datasets/-3e5359fe6b1a603f/tables/-28b905709f94ecc7/rowAccessPolicies
java.lang.IllegalArgumentException: java.net.MalformedURLException: no protocol: projects/2af774bb308513d5/datasets/-3e5359fe6b1a603f/tables/-28b905709f94ecc7/rowAccessPolicies
at com.google.api.client.http.GenericUrl.parseURL(GenericUrl.java:679)
at com.google.api.client.http.GenericUrl.<init>(GenericUrl.java:125)
at com.google.api.client.http.GenericUrl.<init>(GenericUrl.java:108)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.buildHttpRequestUrl(AbstractGoogleClientRequest.java:373)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.buildHttpRequest(AbstractGoogleClientRequest.java:404)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:514)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:455)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:565)
at com.airwallex.data.grpc.das.service.ResourceAccessServiceTest$setUp$1.invoke(ResourceAccessServiceTest.kt:67)
at com.airwallex.data.grpc.das.service.ResourceAccessServiceTest$setUp$1.invoke(ResourceAccessServiceTest.kt:67)
at io.mockk.impl.eval.RecordedBlockEvaluator$record$block$1.invoke(RecordedBlockEvaluator.kt:25)
at io.mockk.impl.eval.RecordedBlockEvaluator$enhanceWithRethrow$1.invoke(RecordedBlockEvaluator.kt:78)
at io.mockk.impl.recording.JvmAutoHinter.autoHint(JvmAutoHinter.kt:23)
at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:40)
at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:30)
at io.mockk.MockKDsl.internalEvery(API.kt:93)
at io.mockk.MockKKt.every(MockK.kt:98)
at com.airwallex.data.grpc.das.service.ResourceAccessServiceTest.setUp(ResourceAccessServiceTest.kt:67)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeAllMethod(TimeoutExtension.java:68)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllMethods$9(ClassBasedTestDescriptor.java:384)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllMethods(ClassBasedTestDescriptor.java:382)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:196)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:78)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:136)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
The key error info is
java.net.MalformedURLException: no protocol: projects/2af774bb308513d5/datasets/-3e5359fe6b1a603f/tables/-28b905709f94ecc7/rowAccessPolicies
The exception is thrown in the every{} block in setUp function. It seems the url built inside the SDK is invalid, without protocol header. But I don't know how to solve the problems
So what you really want is a way to decouple the code under test from BigQuery. The better way to do so that is to hide BigQuery behind your own abstraction (e.g. an interface) and make the code that needs to query only depend on that abstraction - look up the dependency inversion principle/dependency injection (I've got some answers here that show examples). That way, you can substitute a fake implementation in for testing that, say, queries against a collection in memory.
There is still one problem with this approach. You do at some point need to test against BigQuery for real. Otherwise, how will you prove that component works? I guess the possibilities here are constrained by what your company allows.

How to inject HTTP client from library in Micronaut app?

I have an external http client to other service and I've imported it to my micronaut app but receives an error which points:
Caused by: io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [xxx.files.client.micronaut.FilesClient] exists. Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
I've added these classes when the app starts:
object TransformerApplication {
#JvmStatic
fun main(args: Array<String>) {
Micronaut.build()
.packages(
"xxx.transformer",
"xxx.files.client.micronaut"
)
.mainClass(TransformerApplication.javaClass)
.start()
}
}
But when creating:
#KafkaListener("transformer-group")
class EventsConsumerImpl(private val xlsTransformer: XlsTransformer,
private val filesClient: FilesClient,
private val workspacesClient: WorkspacesClient) : EventsConsumer {
...
}
My http-client:
#io.micronaut.http.client.annotation.Client("\${files.url}")
interface FilesClient {
companion object {
const val FILES_TOKEN_KEY = "FILES"
}
#FilesTokenVerification
#Get("\${files.url}/{fileId}")
fun getFile(#PathVariable fileId: String): ByteArray
#FilesTokenVerification
#Patch("\${files.url}/{fileId}/info")
fun updateFileStatus(#PathVariable fileId: String, #Body metadata: Metadata): Metadata
#FilesTokenVerification
#Get("\${files.url}/{fileId}/info")
fun getFileMetadata(#PathVariable fileId: String): Metadata
}```
Can someone explain to me what I'm doing wrong?
is usuallay use a factory for that:
https://docs.micronaut.io/latest/guide/index.html#factories
but i do not know if that works with declarative clients.
Maybe try a wrapper around.

NullPointerException while setting Resource Bundle in Codenameone

I am testing translation in codename one, just used the Chrome Example added code to read "en" local I think, and I am receiving this exception, here is the code, thank you
public class Chrome {
private Resources theme;
private Form current;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
}
public void start() {
String local = L10NManager.getInstance().getLanguage();
System.err.println("local: "+local);
UIManager.getInstance().setBundle(theme.getL10N("l10n", local));
Here is Output:
local: en
java.lang.NullPointerException
at com.codename1.ui.util.Resources.getL10N(Resources.java:834)
at com.codename1.demo.chrome.Chrome.start(Chrome.java:39)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.codename1.impl.javase.Executor$3$1.run(Executor.java:258)
at com.codename1.ui.Display.processSerialCalls(Display.java:1331)
at com.codename1.ui.Display.mainEDTLoop(Display.java:1125)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
Java Result: 1
This NPE will happen if there's no localization resource named "l10n" in the resource bundle. You need to add a localization bundle and name it exactly (case sensitive no spaces) "l10n".

REST client interface can not be injected in Quarkus kotlin app

I tried to add a quarkus-rest-client sample for my post-service which is a simple REST API built with Quarkus.
The java version is working well.
When I added another Kotlin to test the kotlin and Gradle support in Quarkus, it failed, the REST Client interface can not be injected as CDI bean.
The PostControlloer is Jaxrs resource to expose an aggregated APIs that combined the original two APIs.
#Path("/api")
#RequestScoped
class PostController(#Inject #RestClient val client: PostResourceClient) {
// #Inject
// #RestClient
// lateinit var client: PostServiceClient
#GET
#Produces(MediaType.APPLICATION_JSON)
fun getPosts(#QueryParam("q")
q: String,
#QueryParam("offset")
#DefaultValue("0")
offset: Int,
#QueryParam("limit")
#DefaultValue("10")
limit: Int): Response {
val posts = this.client.getAllPosts(q, offset, limit).entity as List<Post>
val count = this.client.countAllPosts(q).entity as Long
return ok(PostPage(posts, count)).build()
}
}
The above two approaches to inject a Bean are failed.
The REST Client interface:
#Path("/posts")
#RegisterRestClient
interface PostResourceClient {
#GET
#Produces(MediaType.APPLICATION_JSON)
fun getAllPosts(
#QueryParam("q")
q: String,
#QueryParam("offset")
#DefaultValue("0")
offset: Int,
#QueryParam("limit")
#DefaultValue("10")
limit: Int
): Response
#GET
#Path("count")
#Produces(MediaType.APPLICATION_JSON)
fun countAllPosts(
#QueryParam("q")
q: String
): Response
}
The application config for this Rest Client interface.
com.example.PostResourceClient/mp-rest/url=http://localhost:8080
com.example.PostResourceClient/mp-rest/scope=javax.inject.Singleton
The complete codes is here.
Duplicated with Error to inject some dependency with kotlin + quarkus it is a MicroProfile RestClient issue. See the workaround in the original SO answer:
#Inject
#field: RestClient
lateinit internal var countriesService: CountriesService
An issue is already openned on MicroProfile RestClient to have a fix for this and tracked on the Quarkus issue traker: https://github.com/quarkusio/quarkus/issues/5413

How can we use Dagger2 with kotlin?

I want use Dagger2 with kotlin. But then I use this setting for dagger2 with kotlin by the way on the internet, it occurs a problem.
//build.gradle
apply plugin: 'kotlin-kapt'
kapt {
generateStubs = true
}
...
dependencies {
compile 'com.google.dagger:dagger-android:2.11'
compile 'com.google.dagger:dagger-android-support:2.11'
kapt 'com.google.dagger:dagger-android-processor:2.11'
kapt 'com.google.dagger:dagger-compiler:2.11'
}
Here a problem, I am using Lombok too. Is this the problem?
e: java.lang.IllegalStateException: failed to analyze: org.jetbrains.kotlin.kapt3.diagnostic.KaptError: Error while annotation processing
at org.jetbrains.kotlin.analyzer.AnalysisResult.throwIfError(AnalysisResult.kt:57)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules(KotlinToJVMBytecodeCompiler.kt:137)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:158)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:61)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:107)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:51)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:92)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$2.invoke(CompileServiceImpl.kt:386)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$2.invoke(CompileServiceImpl.kt:96)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:892)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:96)
at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:137)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:919)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:891)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:385)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.jetbrains.kotlin.kapt3.diagnostic.KaptError: Error while annotation processing
at org.jetbrains.kotlin.kapt3.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:90)
at org.jetbrains.kotlin.kapt3.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:42)
at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.runAnnotationProcessing(Kapt3Extension.kt:205)
at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:166)
at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:82)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM$analyzeFilesWithJavaIntegration$2.invoke(TopDownAnalyzerFacadeForJVM.kt:96)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:106)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:83)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:376)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:67)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:96)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:367)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules(KotlinToJVMBytecodeCompiler.kt:132)
... 30 more
:app:kaptStagingDebugKotlin FAILED
FAILURE: Build failed with an exception.
MenuActivity
abstract class MenuActivity : BaseFragmentActivity() {
#Inject
internal var presenter: MenuPresenter? = null
override fun baseFragmentWithTag(): Map<String, Class<out BaseManagerFragment>> {
val map = HashMap<String, Class<out BaseManagerFragment>>()
for (tag in MenuScreensTag.values())
map.put(tag.getTag(), tag.getFragmentClazz())
return map
}
#JvmOverloads
fun switchTag(screensTag: MenuScreensTag, clearCurrentStack: Boolean = false) {
val tag = screensTag.getTag()
switchToStackByTag(tag, clearCurrentStack)
}
public override fun inject(appComponent: AppComponent) {
val component = DaggerMenuComponent.builder()
.appComponent(appComponent)
.menuModule(MenuModule(this))
.build()
component.injectFragment(this)
component.injectPresenter(presenter!!)
}
}
Here is the MenuActivity code.
I just use kotlin plugin to convert java to kotlin directly. Then the error occurs.
Like you assumed already, Lombok is the problem. Kapt runs before Lombok and thus some relevant classes or at least parts of it don't exist yet. Therefore compilation fails.
In our case we replaced Lombok with Kotlin data classes in one go. Alternatively you can move all these classes to a separate module which builds before you run Kapt the first time. If you don't have to many classes you could also de-lombok these or implement what you need manually.
Thank you all,
I have solved this.
make
#Inject
internal var presenter: MenuPresenter? = null
to
#Inject
lateinit var presenter: MenuPresenter? = null