Skip to content

Kotlin. Unnecessary reflection for Sealed classes #1355

Open
@alisevych

Description

@alisevych

Description

Unnecessary reflection is used in generated tests for Sealed classes in Kotlin

To Reproduce

  1. IDEA Ultimate 2022.2.3 with one of the latest plugin built from main, f.i. installed
  2. Create/open a project with Kotlin
  3. Use plugin to generate tests for the code with default settings:
class SealedClasses {
    fun eval(expr: Expr): Int =
    when (expr) {
        is Num -> expr.value
        is Sum -> eval(expr.left) + eval(expr.right)
    }

    sealed interface Expr
    sealed class ExprC(): Expr
    class Num(val value: Int) : ExprC()
    class Sum(val left: Expr, val right: Expr) : ExprC()
}

Expected behavior

Tests are supposed to be generated without reflection.

Actual behavior

There is unneeded reflection in generated tests.

Visual proofs (screenshots, logs, images)

    @Test
    fun testEval2() {
        val sealedClasses = SealedClasses()
        val sum = (createInstance("org.utbot.examples.classes.SealedClasses\$Sum") as Sum)
        val num = (createInstance("org.utbot.examples.classes.SealedClasses\$Num") as Num)
        setField(num, "org.utbot.examples.classes.SealedClasses\$Num", "value", 0)
        setField(sum, "org.utbot.examples.classes.SealedClasses\$Sum", "left", num)
        setField(sum, "org.utbot.examples.classes.SealedClasses\$Sum", "right", num)
        
        val sealedClassesClazz = Class.forName("org.utbot.examples.classes.SealedClasses")
        val sumType = Class.forName("org.utbot.examples.classes.SealedClasses\$Expr")
        val evalMethod = sealedClassesClazz.getDeclaredMethod("eval", sumType)
        evalMethod.setAccessible(true)
        val evalMethodArguments = Array<Any?>(1) { null }
        evalMethodArguments[0] = sum
        val actual = (evalMethod.invoke(sealedClasses, *evalMethodArguments) as Int)
        
        assertEquals(0, actual)
    }

Environment

Windows 10 Pro
IntelliJ IDEA 2022.2.3
Gradle
JDK 11

Additional context

The following test would be expected:

    @Test
    fun testEval1() {
        val sealedClasses = SealedClasses()
        val num1 = Num(1)
        val num2 = Num(2)
        val sum = Sum(num1,num2)

        val actual = sealedClasses.eval(sum)

        assertEquals(3, actual)
    }

Metadata

Metadata

Assignees

Labels

ctg-bugIssue is a buglang-kotlinIssue is related to Kotlin language support

Type

No type

Projects

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions