UnitTest cannot import internal classes

I’m creating a kotlin library, many interfaces are public and their implementations are internal.

I cannot import internal implementation classes in UnitTest(My IDE is IntelliJ IDEA 2021.3.1 (Community Edition)).

What’s the problem? How can I import internal types in UnitTests

You can’t, and you shouldn’t need to: automated tests are useful to ensure non regression (new bugs don’t appear in the future). If we were to test private or internal behavior, then any refactor would mean rewriting the tests—thus increasing work and decreasing their usefulness.

The ‘proper way’ is to test public methods to check that they respect their contract and documentation (eg. what the other modules have access to), and use code coverage to check whether all internal cases are handled or not. If some internal code cannot be accessed through the public API, then why is it here?

If your codebase is large enough that testing internal behavior becomes important, then it means that your modules are too large. You should split your project into multiple modules, and have your public API depend on your internal/library modules with the implementation scope. Then, your internal modules can have public declarations that can be called in their own tests, without them being available for the end-user of your main module. Bonus point, this also increases build performance (parallel module compilation) and code organization (each module should be a few hundred files big at most, and have clearly defined concerns, so different teams can work on different modules without worrying about refactoring the internals that other teams use—since they can’t).

I do not agree.

I just tested in a Gradle Kotlin+java library module, and importing internal classes from main source set into the test source set of the same module works.

I’ve also found a confirmation here.

Are you using a Maven or Gradle project ? Are your tests located in the same module as your implementations ?

And finally, even if testing public APIs is essential, sometimes you might want to test the behavior of an internal piece of code, especially when the surface of your public API is small in comparison to internal code.

I find it very practical then to have automated tests that verify behaviour of internal pieces of code. For one, it helps maintainers to quickly locate regressions, and for two, when you’re creating large components, it helps to validate your work step by step.