Argument passed to when() is not a mock! Example of correct stubbing: doThrow(new RuntimeException()).when(mock).someMethod(); - kotlin

When using Mockito in JUnit4, I encounter the error in the title.
My code is shown below
package cn.patest.judgerAutoscalerKotlin
import org.junit.Test
import org.mockito.*
import java.lang.RuntimeException
class CalculateScaleToTest {
#Mock
private lateinit var test: cn.patest.judgerAutoscalerKotlin.Test
private fun mockTest() {
test = cn.patest.judgerAutoscalerKotlin.Test()
Mockito.doAnswer { 1 }.`when`(test).test()
}
#Test
fun z() {
mockTest()
}
}
package cn.patest.judgerAutoscalerKotlin
class Test() {
fun test(): Int {
return 1
}
}
Error details are shown below:
org.mockito.exceptions.misusing.NotAMockException:
Argument passed to when() is not a mock!
Example of correct stubbing:
doThrow(new RuntimeException()).when(mock).someMethod();
at cn.patest.judgerAutoscalerKotlin.CalculateScaleToTest.mockTest(CalculateScaleToTest.kt:53)
at cn.patest.judgerAutoscalerKotlin.CalculateScaleToTest.z(CalculateScaleToTest.kt:61)
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 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
I searched with google and found some similar issues but they have different situations from mine.

With:
test = cn.patest.judgerAutoscalerKotlin.Test()
you create a real object, not a mocked one.
Remove the above line and add:
#Before
fun before() {
MockitoAnnotations.initMocks( this )
}
Reference:
Mock
MockitoAnnotations
MockitoAnnotations.initMocks(this) method has to be called to initialize annotated fields.
Note also that mocking the class under test in a real environment doesn't make any sense (in contrast to a MCVE like here).

Related

Deserializing a serialized jackson object with JsonTypeInfo leads to MissmatchedInputException

I am trying to deserialize some JSON data with type info as a wrapper object. Unfortunately I keep getting a cryptic MismatchedInputException:
java.lang.IllegalArgumentException: Unexpected token (VALUE_STRING), expected START_OBJECT: need JSON Object to contain As.WRAPPER_OBJECT type information for class com.cumulocity.connectivity.provider.kite.model.error.ClientException
at [Source: UNKNOWN; line: -1, column: -1]
at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4234)
at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:4165)
at my.jackson.test.ClientExceptionTest.serializeDeserializeTest(ClientExceptionTest.java:23)
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.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (VALUE_STRING), expected START_OBJECT: need JSON Object to contain As.WRAPPER_OBJECT type information for class com.cumulocity.connectivity.provider.kite.model.error.ClientException
at [Source: UNKNOWN; line: -1, column: -1]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:1650)
at com.fasterxml.jackson.databind.DeserializationContext.reportWrongTokenException(DeserializationContext.java:1400)
at com.fasterxml.jackson.databind.jsontype.impl.AsWrapperTypeDeserializer._deserialize(AsWrapperTypeDeserializer.java:100)
at com.fasterxml.jackson.databind.jsontype.impl.AsWrapperTypeDeserializer.deserializeTypedFromObject(AsWrapperTypeDeserializer.java:52)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1209)
at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:68)
at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4229)
... 24 more
Here is how I modelled the ClientException class:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import lombok.Data;
import lombok.NoArgsConstructor;
#NoArgsConstructor
#Data
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonTypeInfo(
include = As.WRAPPER_OBJECT,
use = Id.NAME
)
public class ClientException {
private String exceptionCategory;
private String exceptionId;
private String text;
}
The following JUnit4 test produces the exception:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import static org.junit.Assert.*;
#Slf4j
public class ClientExceptionTest {
#Test
public void serializeDeserializeTest() throws JsonProcessingException {
ClientException clientException = new ClientException();
clientException.setExceptionId("someId");
clientException.setExceptionCategory("someCat");
clientException.setText("someText");
ObjectMapper mapper = new ObjectMapper();
String clientExceptionString = mapper.writeValueAsString(clientException);
ClientException actual = mapper.convertValue(clientExceptionString, ClientException.class);
assertEquals(clientException, actual);
}
}
I am not sure if I'm missing something in my model. Any help would be appreciated.
It turns out that ObjectMapper.readValue should be used, because ObjectMapper.convertValue does not support polymorphic typing.
Thanks to cowtowncoder for the quick answer on here.

Verification of a deep mock via mockContstructor fails

In a test I want to verify that a model would call a client when a method of this model is called.
The class under test - the model class - is an object singleton. (KubernetesResourceModel.kt)
object KubernetesResourceModel {
…
private fun createClient(): NamespacedKubernetesClient {
return DefaultKubernetesClient(ConfigBuilder().build())
}
The actual call to the client - DefaultKubernetesClient - happens in an instance variable within KubernetesResourceModel (Cluster.kt)
class Cluster(val client: NamespacedKubernetesClient) {
...
private fun loadAllNameSpaces(): Sequence<Namespace> {
return client.namespaces().list().items.asSequence()
}
In my test I stub the client and then verify that a call to the client library is executed when KubernetesResourceModel.getAllNamespaces is called, (KubernetesResourceModelTest.kt):
#Test
fun `should call list namespaces on client`() {
// given
mockClient(emptyList())
// when
KubernetesResourceModel.getAllNamespaces()
// then
verify { anyConstructed<DefaultKubernetesClient>().namespaces().list().items }
}
...
private fun mockClient(namespaces: List<Namespace>) {
// client.namespaces().list().items.asSequence()
mockkConstructor(DefaultKubernetesClient::class)
every { anyConstructed<DefaultKubernetesClient>().namespaces() } returns
spyk {
every { list() } returns
spyk {
every { items } returns
namespaces
}
every { watch(any()) } returns
mockk()
}
The mocking works and I see KubernetesResourceModel.getAllNamespaces() returning the empty list that I passed along when mocking (mockClient(emptyList())).
Unfortunately the verification
verify { anyConstructed<DefaultKubernetesClient>().namespaces().list().items } (KubernetesResourceModelTest.kt)
fails telling me that no call on client.namespaces().list() happened:
Verification failed: call 2 of 3: NonNamespaceOperation(child of mockkConstructor<DefaultKubernetesClient>()#1).list()) was not called
java.lang.AssertionError: Verification failed: call 2 of 3: NonNamespaceOperation(child of mockkConstructor<DefaultKubernetesClient>()#1).list()) was not called
at io.mockk.impl.recording.states.VerifyingState.failIfNotPassed(VerifyingState.kt:66)
at io.mockk.impl.recording.states.VerifyingState.recordingDone(VerifyingState.kt:42)
at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:47)
at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:60)
at io.mockk.impl.eval.VerifyBlockEvaluator.verify(VerifyBlockEvaluator.kt:30)
at io.mockk.MockKDsl.internalVerify(API.kt:118)
at io.mockk.MockKKt.verify(MockK.kt:139)
at io.mockk.MockKKt.verify$default(MockK.kt:136)
at org.jboss.tools.intellij.kubernetes.model.KubernetesResourceModelTest.should call list namespaces on client(KubernetesResourceModelTest.kt:32)
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 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
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 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 com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
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 org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch
Any idea what I am missing?

java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory while running as Junit

While trying to run my Karate project as Junit, I am getting the below error.
All of my slf4j dependencies in the .m2 repo looks fine. But couldn't figure out what is the issue. Could you please someone help me to get rid of this issue
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at com.intuit.karate.Runner.<clinit>(Runner.java:51)
at soa.core.ParallelTest.testParallel(ParallelTest.java:27)
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 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 25 more
Here is my Junit Runner class. The exception is thrown at line number 2 of testParallel() method
public class ParallelTest {
#Test
public void testParallel() {
System.setProperty("karate.env", "acpt");
Results results = Runner.parallel(getClass(), 1);
generateReport(results.getReportDir());
assertTrue(results.getErrorMessages(), results.getFailCount() == 0);
}
public static void generateReport(String karateOutputPath) {
Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] {"json"}, true);
List<String> jsonPaths = new ArrayList(jsonFiles.size());
jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
Configuration config = new Configuration(new File("target"), "WTR_EPP");
ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
reportBuilder.generateReports();
}
}
Pretty sure you have a pom.xml that includes a bunch of other dependencies and you will need to resolve JAR / library conflicts yourself.
One suggestion is to create a quickstart project - get that working first - and then compare with the problem project you have.
If you are still stuck - please follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue

ByteBuddy reset fails when running with Eclipse (EclEmma/JaCoCo) Code Coverage

I am redefining classes with ByteBuddy within a unit test. I am resetting the class after each test to ensure no cross-talk between tests.
ByteBuddy works as expected when simply running the tests in the Eclipse IDE or when running with maven command line. But if it run in Eclipse with coverage, resetting the class results in the following exception:
java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)
Bellow is a sample test which passes in the default JUnit runner but fails when run with Code Coverage in Eclipse. Below that is the full stack trace of the failure.
I am using ByteBuddy version 1.8.22 and the EclEmma Java Code Coverage Package version 3.1.0.201804041601.
I am assuming this issue is due to a conflict between ByteBuddy class modifications and EclEmma code instrumentation. It there an alternate approach to restoring class definitions that would work around this issue?
Fails under Coverage:
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import net.bytebuddy.implementation.FixedValue;
public class ByteBuddyEclEmmaTest {
#Test
public void recreateEclEmmaByteBuddyResetIssue() throws Exception {
ByteBuddyAgent.install();
ByteBuddy byteBuddy = new ByteBuddy();
ClassReloadingStrategy classReloadingStrategy = ClassReloadingStrategy.fromInstalledAgent();
byteBuddy
.redefine(X.class)
.method(named("getValue")).intercept(FixedValue.value("faked value"))
.make()
.load(X.class.getClassLoader(), classReloadingStrategy);
X x = new X();
assertThat(x.getValue()).isEqualTo("faked value");
classReloadingStrategy.reset(X.class);
assertThat(x.getValue()).isEqualTo("real value");
}
public class X {
public String getValue() {
return "real value";
}
}
}
Stack Trace:
java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)
at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method)
at sun.instrument.InstrumentationImpl.redefineClasses(InstrumentationImpl.java:170)
at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Strategy$1.apply(ClassReloadingStrategy.java:261)
at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Strategy$1.reset(ClassReloadingStrategy.java:279)
at net.bytebuddy.dynamic.loading.ClassReloadingStrategy.reset(ClassReloadingStrategy.java:209)
at net.bytebuddy.dynamic.loading.ClassReloadingStrategy.reset(ClassReloadingStrategy.java:195)
at ByteBuddyEclEmmaTest.recreateEclEmmaByteBuddyResetIssue(ByteBuddyEclEmmaTest.java:30)
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 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
I figured out my issue was caused by an older version of ByteBuddy. I was getting version 1.6.14 pulled into my project from Mockito. When I explicitly brought in ByteBuddy version 1.8.22, the test runs successfully, both with and without Coverage.

Kotlin generic issue, should be subtype of Nothing

I'm writing a simple Spring test on Kotlin and have a compilation error with generics that I can't understand. The function is below:
#Test
fun actuatorRootReturnsOnlyAllowed() {
val expectBody:WebTestClient.BodySpec<Map<String, Map<String, Any>>, *> = client!!.get().uri("/app")
.accept(MediaType.APPLICATION_JSON_UTF8)
.exchange()
.expectStatus().isOk
.expectBody(object : ParameterizedTypeReference<Map<String, Map<String, Any>>>() {})
expectBody.consumeWith<Map<String, Map<String, Any>>> { result->
val actuatorLinks = result.responseBody!!["_links"]
Assert.assertTrue(actuatorLinks!!.containsKey("self"))
Assert.assertTrue(actuatorLinks.containsKey("health"))
Assert.assertTrue(actuatorLinks.containsKey("info"))
Assert.assertTrue(actuatorLinks.containsKey("loggers"))
Assert.assertTrue(actuatorLinks.containsKey("loggers-name"))
}
}
The problem is in line expectBody.consumeWith. For some reason Kotlin expects type Nothing with the compilation error: Error:(53, 32) Kotlin: Type argument is not within its bounds: should be subtype of 'Nothing!'.
Actual type of consumeWith method is EntityExchangeResult<T>, however method still expects Nothing. I would expect something like expectBody.consumeWithEntityExchangeResult<<Map<String, Map<String, Any>>>> or expectBody.consumeWith<Map<String, Map<String, Any>>> instead.
However with type Nothing I get the NullPointerException:
java.lang.NullPointerException
at com.example.ActuatorEndpointsTest.actuatorRootReturnsOnlyAllowed(ActuatorEndpointsTest.kt:52)
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:564)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
Below is the same working equivalent in Java:
#Test
public void actuatorRootReturnsOnlyAllowed() {
client.get().uri("/app")
.accept(MediaType.APPLICATION_JSON_UTF8)
.exchange()
.expectStatus().isOk()
.expectBody(new ParameterizedTypeReference<Map<String, Map<String, Object>>>(){})
.consumeWith(result -> {
final Map<String, Object> actuatorLinks = result.getResponseBody().get("_links");
assertTrue(actuatorLinks.containsKey("self"));
assertTrue(actuatorLinks.containsKey("health"));
assertTrue(actuatorLinks.containsKey("info"));
assertTrue(actuatorLinks.containsKey("loggers"));
assertTrue(actuatorLinks.containsKey("loggers-name"));
});
}
Can anyone explain the reason why Kotlin expects Nothing and how this code can be corrected?