diff --git a/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/instantiator/KotlinInstantiator.kt b/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/instantiator/KotlinInstantiator.kt index ccc9f1b7e..7f98f5e06 100644 --- a/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/instantiator/KotlinInstantiator.kt +++ b/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/instantiator/KotlinInstantiator.kt @@ -41,19 +41,19 @@ import com.navercorp.fixturemonkey.api.property.Property import com.navercorp.fixturemonkey.api.property.PropertyUtils import com.navercorp.fixturemonkey.api.type.TypeReference import com.navercorp.fixturemonkey.api.type.Types -import com.navercorp.fixturemonkey.api.type.Types.getDeclaredConstructor import com.navercorp.fixturemonkey.kotlin.introspector.CompanionObjectFactoryMethodIntrospector import com.navercorp.fixturemonkey.kotlin.introspector.KotlinPropertyArbitraryIntrospector import com.navercorp.fixturemonkey.kotlin.property.KotlinPropertyGenerator import com.navercorp.fixturemonkey.kotlin.type.actualType +import com.navercorp.fixturemonkey.kotlin.type.declaredConstructor import com.navercorp.fixturemonkey.kotlin.type.toTypeReference import kotlin.reflect.KFunction import kotlin.reflect.KParameter import kotlin.reflect.KProperty import kotlin.reflect.full.companionObject import kotlin.reflect.full.memberFunctions +import kotlin.reflect.jvm.javaConstructor import kotlin.reflect.jvm.javaType -import kotlin.reflect.jvm.kotlinFunction class KotlinInstantiatorProcessor : InstantiatorProcessor { @@ -74,8 +74,7 @@ class KotlinInstantiatorProcessor : ): InstantiatorProcessResult { val parameterTypes = instantiator.inputParameterTypes.map { it.type.actualType() }.toTypedArray() - val declaredConstructor = getDeclaredConstructor(typeReference.type.actualType(), *parameterTypes) - val kotlinConstructor = declaredConstructor.kotlinFunction!! + val kotlinConstructor: KFunction<*> = typeReference.type.actualType().declaredConstructor(*parameterTypes) val parameters: List = kotlinConstructor.parameters val inputParameterTypes = instantiator.inputParameterTypes @@ -85,14 +84,13 @@ class KotlinInstantiatorProcessor : val resolveParameterTypes = resolveParameterTypes(parameterTypeReferences, inputParameterTypes) val resolveParameterName = resolvedParameterNames(parameterNames, inputParameterNames) - val constructorParameterProperties = parameters.mapIndexed { index, kParameter -> val resolvedParameterTypeReference = resolveParameterTypes[index] val resolvedParameterName = resolveParameterName[index] ConstructorProperty( resolvedParameterTypeReference.annotatedType, - declaredConstructor, + kotlinConstructor.javaConstructor, resolvedParameterName, null, kParameter.type.isMarkedNullable, @@ -101,7 +99,7 @@ class KotlinInstantiatorProcessor : val constructorArbitraryIntrospector = ConstructorArbitraryIntrospector( ConstructorWithParameterNames( - declaredConstructor, + kotlinConstructor.javaConstructor, resolveParameterName, ), ) diff --git a/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/type/KotlinTypes.kt b/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/type/KotlinTypes.kt index 3d4524aca..c98040ee4 100644 --- a/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/type/KotlinTypes.kt +++ b/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/type/KotlinTypes.kt @@ -28,6 +28,7 @@ import java.lang.reflect.ParameterizedType import java.lang.reflect.Type import java.lang.reflect.TypeVariable import kotlin.reflect.KFunction +import kotlin.reflect.KParameter import kotlin.reflect.KProperty import kotlin.reflect.KType import kotlin.reflect.full.findAnnotations @@ -172,3 +173,15 @@ fun KType.toTypeReference(): TypeReference<*> = object : TypeReference() { return this@toTypeReference.javaType.toAnnotatedType() } } + +fun Class<*>.declaredConstructor( + vararg arguments: Class<*>, +): KFunction<*> = this.kotlin.constructors + .firstOrNull { constructor -> + Types.isAssignableTypes( + arguments, + constructor.parameters.filter { it.kind != KParameter.Kind.INSTANCE } + .map { it.type.javaType.actualType() } + .toTypedArray(), + ) + } ?: this.kotlin.constructors.first() diff --git a/fixture-monkey-tests/kotlin-tests/src/test/kotlin/com/navercorp/fixturemonkey/tests/kotlin/InstantiatorTest.kt b/fixture-monkey-tests/kotlin-tests/src/test/kotlin/com/navercorp/fixturemonkey/tests/kotlin/InstantiatorTest.kt index 52560c966..6383ef83e 100644 --- a/fixture-monkey-tests/kotlin-tests/src/test/kotlin/com/navercorp/fixturemonkey/tests/kotlin/InstantiatorTest.kt +++ b/fixture-monkey-tests/kotlin-tests/src/test/kotlin/com/navercorp/fixturemonkey/tests/kotlin/InstantiatorTest.kt @@ -3,8 +3,8 @@ package com.navercorp.fixturemonkey.tests.kotlin import com.navercorp.fixturemonkey.FixtureMonkey import com.navercorp.fixturemonkey.api.instantiator.Instantiator import com.navercorp.fixturemonkey.kotlin.KotlinPlugin -import com.navercorp.fixturemonkey.kotlin.instantiator.instantiateBy import com.navercorp.fixturemonkey.kotlin.giveMeBuilder +import com.navercorp.fixturemonkey.kotlin.instantiator.instantiateBy import com.navercorp.fixturemonkey.tests.TestEnvironment.TEST_COUNT import org.assertj.core.api.BDDAssertions.then import org.junit.jupiter.api.RepeatedTest @@ -419,6 +419,18 @@ class InstantiatorTest { then(actual).isNotNull() } + @RepeatedTest(TEST_COUNT) + fun instantiateWithDefaultArgument() { + class ConstructorObject(val value: String = "default") + + val actual = SUT.giveMeBuilder() + .instantiateBy { constructor() } + .sample() + .value + + then(actual).isNotNull + } + class Foo(val foo: String, val bar: Int) { constructor(foo: String) : this(foo, 1)