Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pablisco/d7c1841bf5a476dc2c013950815ce44c to your computer and use it in GitHub Desktop.
Save pablisco/d7c1841bf5a476dc2c013950815ce44c to your computer and use it in GitHub Desktop.
Creating subjects in tests with private constructors
@JvmOverloads
fun <T> createForTests(
type: Class<T>,
whenever: ((index: Int, Constructor<T>) -> Boolean),
vararg arguments: Any = emptyArray()
) = createForTests(type, *arguments, whenever)
@JvmOverloads
@Suppress("UNCHECKED_CAST")
fun <T> createForTests(
type: Class<T>,
vararg arguments: Any = emptyArray(),
whenever: ((index: Int, Constructor<T>) -> Boolean) = { _, _ -> true }
): T =
constructorFor(type, whenever)
.newInstance(*arguments)
?: error("Could not create instance of ${type.simpleName}")
@Suppress("UNCHECKED_CAST")
fun <T> constructorFor(type: Class<T>, whenever: (index: Int, Constructor<T>) -> Boolean): Constructor<T> =
type.constructors
.let { it as? Array<Constructor<T>> }
?.filterIndexed(whenever)
?.first()
?.also { it.isAccessible = true }
?: error("Could not find constructor for ${type.simpleName}")
inline fun <reified T> createForTests(
vararg arguments: Any = emptyArray(),
noinline whenever: ((index: Int, Constructor<T>) -> Boolean) = { _, _ -> true }
): T = createForTests(T::class.java, arguments, whenever = whenever)
inline fun <reified T> constructorFor(
noinline whenever: ((index: Int, Constructor<T>) -> Boolean) = { _, _ -> true }
): Constructor<T> = constructorFor(T::class.java, whenever = whenever)
Subject subject = createForTests(Subject.class);
Subject subjectWithIndex = createForTests(Subject.class, new Object[0], (index, c) -> index == 0);
Subject subjectWithCondition = createForTests(Subject.class, new Object[0], (index, c) ->
ArraysKt.contains(c.getParameterTypes(), String.class)
);
Subject subjectWithParams = createForTests(Subject.class, "name");
Subject subjectWithIndexAndParams = createForTests(Subject.class, (index, c) -> index == 0, "name");
val subject = createForTests<Subject>()
val subjectWithIndex = createForTests<Subject> { index, _ -> index == 0 }
val subjectWithCondition = createForTests<Subject> { _, constructor ->
(constructor.parameterTypes ?: emptyArray<Any>()).contentEquals(arrayOf(String::class.java))
}
val subjectWithParams = createForTests<Subject>("name")
val subjectWithIndexAndParams = createForTests<Subject>("name") { index, _ -> index == 0 }
val subjectConstructor = constructorFor<Subject>()
val subjectFromConstructor = subjectConstructor.newInstance("name")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment