Reputation: 3797
I'm giving Kotlin a whirl and was converting the test below that was running fine in Java to Kotlin. After converting the test using the IntelliJ conversion tool I tried to run it but I got this error:
22:32:19.476 [main] DEBUG org.springframework.test.context.junit4.SpringJUnit4ClassRunner - SpringJUnit4ClassRunner constructor called with [class com.test.app.web.DeveloperControllerTest]
22:32:19.486 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate]
22:32:19.494 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)]
22:32:19.517 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [com.test.app.web.DeveloperControllerTest] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper]
22:32:19.539 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.test.app.web.DeveloperControllerTest], using SpringBootContextLoader
22:32:19.543 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.test.app.web.DeveloperControllerTest]: class path resource [com/test/app/web/DeveloperControllerTest-context.xml] does not exist
22:32:19.544 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.test.app.web.DeveloperControllerTest]: class path resource [com/test/app/web/DeveloperControllerTestContext.groovy] does not exist
22:32:19.544 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.test.app.web.DeveloperControllerTest]: no resource found for suffixes {-context.xml, Context.groovy}.
22:32:19.545 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.test.app.web.DeveloperControllerTest]: DeveloperControllerTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
java.lang.StackOverflowError
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at java.util.concurrent.ConcurrentHashMap.containsKey(ConcurrentHashMap.java:964)
at java.lang.reflect.WeakCache.containsValue(WeakCache.java:175)
at java.lang.reflect.Proxy.isProxyClass(Proxy.java:791)
at java.lang.reflect.Proxy.getInvocationHandler(Proxy.java:815)
at sun.reflect.annotation.AnnotationInvocationHandler.asOneOfUs(AnnotationInvocationHandler.java:226)
at sun.reflect.annotation.AnnotationInvocationHandler.equalsImpl(AnnotationInvocationHandler.java:201)
at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:64)
at com.sun.proxy.$Proxy13.equals(Unknown Source)
at java.util.HashMap.putVal(HashMap.java:634)
at java.util.HashMap.put(HashMap.java:611)
at java.util.HashSet.add(HashSet.java:219)
at org.springframework.boot.test.context.ImportsContextCustomizer$ContextCustomizerKey.collectElementAnnotations(ImportsContextCustomizer.java:239)
at org.springframework.boot.test.context.ImportsContextCustomizer$ContextCustomizerKey.collectClassAnnotations(ImportsContextCustomizer.java:226)
Java test:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class DeveloperControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void createNewDeveloper() throws Exception {
mvc.perform(
post("/api/v1/developers")
.param("username", "boaty")
.param("email", "[email protected]")
.param("password", "123loveboats")
.param("passwordConfirmation", "123loveboats")
).andExpect(status().isCreated());
}
}
Converted to Kotlin:
@RunWith(SpringRunner::class)
@SpringBootTest
@AutoConfigureMockMvc
class DeveloperControllerTest {
@Autowired
lateinit var mvc: MockMvc
@Test
@Throws(Exception::class)
fun createNewDeveloper() {
mvc.perform(
post("/api/v1/developers")
.param("username", "boaty")
.param("email", "[email protected]")
.param("password", "123loveboats")
.param("passwordConfirmation", "123loveboats"))
.andExpect(status().isCreated)
}
}
What I've noticed with this is that if I remove the annotation AutoConfigureMockMvc
Spring will boot and try to run, but it'll fail because it can't autowire MockMvc
.
I'm using Kotlin 1.0.1-2 together with Spring Boot 1.4.0-M2.
Upvotes: 3
Views: 25267
Reputation: 774
try adding
@ComponentScan(basePackages = arrayOf("YourAppBasePackage"))
@SpringBootTest(classes = arrayOf(MyExampleApplication::class))
This solved the issue for me
Upvotes: 4
Reputation: 116091
The stack overflow is occurring when Spring Boot attempts to introspect the annotations on DeveloperControllerTest
.
DeveloperControllerTest
is annotated with kotlin.Metadata
. Metadata
is annotated with kotlin.annotation.Retention
. Retention
is annotated with kotlin.annotation.Target
and Target
is annotated with itself. Target
being annotated with itself is the cause of the stack overflowing.
It is legal, although probably quite unusual, for an annotation to be used to annotate itself. Spring Boot should probably be more defensive.
Upvotes: 1