37

In case the tests are in a different module than the production code (which is common), what's the best way to make internal functions visible for tests?

In Java, I would have the production code and the test in the same package and make the methods-to-be-tested package-private (plus, add a @VisibleForTest annotation if the only reason for having it package-private rather than private is the test). Unfortunately, Kotlin doesn't have the concept of package-private.

cafce25
  • 15,907
  • 4
  • 25
  • 31
Jan Pomikálek
  • 1,369
  • 2
  • 13
  • 22

3 Answers3

29

Classes and methods marked with internal access modifier will work from within current versions of Kotlin, Gradle and also Intellij for accessing those methods from test classes. The tools consider the main and test source paths as part of the same module.

Did you try this already? And if it failed you should report a bug since this was already reported, fixed and should be fine in any current version.

Jayson Minard
  • 84,842
  • 38
  • 184
  • 227
  • Yes, that's exactly what I have tried with Intellij IDEA 15. I'll double-check I'm at the latest version of both the IDE and the Kotlin plug-in and that my setup is correct. – Jan Pomikálek Feb 29 '16 at 12:22
  • Latest Intellij IDEA 15 is 15.0.4, with Kotlin plugin 1.0.0 – Jayson Minard Feb 29 '16 at 12:27
  • It's working correctly now and I haven't even installed any updates. I have probably done something wrong before and got confused. Cool that it's working! Thanks. – Jan Pomikálek Mar 05 '16 at 21:48
  • 4
    Unless I'm doing something similarly wrong it doesn't seem to work from non-Kotlin unit tests, though (Spock + Groovy in my case) :( – Gregor Petrin Mar 27 '17 at 13:17
  • > The tools consider the main and test source paths as part of the same module. Where does this magic happen? I am trying to use Buck to build and run my Kotlin tests. – bolinfest Mar 22 '19 at 21:40
  • @bolinfest Please ask that as a new question, Buck likely is not setting them up the compilation module in the same way that Intellij, Eclipse, Maven, and Gradle do to make this work. And Buck is a unique creature. – Jayson Minard Mar 24 '19 at 12:57
  • @GregorPetrin The Spock issue doesn't seem to be solved yet: https://youtrack.jetbrains.com/issue/KT-525 – neu242 Jun 20 '22 at 05:59
  • This doesn't seem to be true as of Kotlin 1.8.20... – Fudge Fudge May 15 '23 at 19:35
6

Probably the easiest solution is to place your unit tests depending on internal code in the same module with the production сode and leave only the integration tests, which use public API, in the separate module.

This seems reasonable since the internal modifier means exactly the visibility inside the same module.

hotkey
  • 140,743
  • 39
  • 371
  • 326
1

In my case it didn't work because we renamed our projects inside settings.gradle to add a prefix and Kotlin didn't seem to like that.

Once we removed the lines renaming the projects, we were able to see internal members from main/ inside test/.

Franklin Wang
  • 233
  • 4
  • 9