In Swift, to test a default access level class, one can put @testable
in the test class header, making the internal access level class accessible and testable from the test package, without everything in the class public. I was wondering if Java has a way to access the same purpose?
How can I test a default access level class in Java from the test package without making everything in the class public?
There are @VisibleForTesting annotations in some java libs, but generally it does not prevent illegal access. Even making package protected does not solve all the issues as still some other classes can use testing code, which can lead to some unexpected behaviour. I recently stumbled upon nice construct that allows you to show the intentions about exposing some methods for tests
public class A{
private int someMethodYouWantToTest(){}
private Testability testability = new Testability();
class Testability{
int exposedMethodForTest(){
someMethodYouWantToTest()
}
}
}
And then in your test class
public class Test{
private A underTest = new A()
public void testHiddenMethod(){
a.testability.exposedMethodForTest()
}
}
This way you private method is private, and only access if by dedicated testability inner class that clearly states its purpose, so no one by accident calls your method outside of tests. This solves issues with package protected businness methods that may be called from other places but were really meant to be private.