How to test kotlin function declared `internal` from within tests when java-test-fixtures module is in use

1.4k Views Asked by At

I've tried to make use of test fixtures in my project in kotlin. Unfortunately I have encountered a strange problem, probably a bug, in a component of the toolchain (not sure which one).

Normally a Kotlin function in main declared internal can be accessible from a unit test from the same package. There's a number of proofs supporting this claim, particularly Kotlin: Make an internal function visible for unit tests

Indeed if we have src/main/kotlin/ main.kt:

@file:JvmName("Main")
package org.example.broken_test_fixtures

internal fun sayHello(who: String): String = "Hello, $who!"

fun main() {
    println(sayHello("world"))
}

and src/test/kotlin/SayHelloTest.kt:

package org.example.broken_test_fixtures

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class SayHelloTest {
    @Test
    fun testSayHello() {
        val expected = "Hello, world!"
        val actual = sayHello("world")
        assertEquals(actual, expected)
    }
}

the test is passed successfully with a regular build.gradle.kts:

plugins {
    kotlin("jvm") version "1.3.61"
}


group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib-jdk8"))
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.5.2")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.5.2")
}

tasks {
    compileKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
    compileTestKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

So far so good.

But with an addition of a single line into the plugins list:

id("java-test-fixtures")

the build of the test gets broken with the following error:

e: /home/work/users/alex/broken-test-fixtures/src/test/kotlin/SayHelloTest.kt: (10, 22): Cannot access 'sayHello': it is internal in 'org.example.broken_test_fixtures'

I've discovered that similar problems were mentioned in Gradle, Kotlin Gradle plugin bug trackers. Unfortunately I couldn't extract a solution from those issues. Perhaps, it's a different problem.

For the reader's convenience I have prepared a tiny repo on Github demonstrating the problem.

1

There are 1 best solutions below

0
On

Since Kotlin 1.3.60 there's an associateWith Gradle Kotlin Plugin API implemented in https://youtrack.jetbrains.com/issue/KT-20760

From 1.9.20 it'll be by default enabled for test fixtures too, as mentioned in https://youtrack.jetbrains.com/issue/KT-34901

For now <1.9.20, this project has all kinds of references: https://github.com/TWiStErRob/repros/tree/main/kotlin/test-fixtures-and-suites-friends

It might show errors in IDEA, but it works in command line. Errors each line fixes are commented in build.gradle.kts, pick the one you need :)