Java testing class with many private methods

I have a class that is responsible for importing contracts from CSV into a database.

In the class itself, there is only one public method that starts the import, and the other methods are all private (because only the class itself will use it and they adhere to the logic).

I am starting to do tests for this class using Spock, and there are many private methods, how can I test it?

Should I use them for verification? Check only the main method publicly available?

Which is better?

+7
java unit-testing junit integration-testing spock
source share
4 answers

In theory, your private methods are ultimately used by one of the public methods, otherwise they are not used at all. Thus, you usually configure your tests to call public methods with the necessary context so that it gets into your private methods.

Unit tests primarily check the compilation unit (i.e. class). You can use unit test methods, but then they should be publicly available, which contradicts the fact that they have a nice clean API.

So, just check your public method to use all private methods. Private methods are internal class mechanics; they do not need to be tested directly.

+11
source share

Some people claim that you should check your API (i.e. your public methods).

A possible solution is to use a private package, so that only those classes from one package can access these methods.

Personally, I would not test private methods, I would focus on public methods that behave as expected. If you feel that your personal methods carry too much weight, then maybe they will do it, and you should further separate the functionality.

+2
source share

You can use reflection to achieve this. The Method class has a setAcessible (boolean) method that allows you to call it even if it is declared as private / protected / default. See the example below:

YourClass yourClassInstance = new YourClass(); Method yourMethod = YourClass.class.getDeclaredMethod("yourMethod", null); yourMethod.setAccessible(true); Object[] parameters = new Object[1]; parameters[0] = "A String parameter"; Object result = yourMethod.invoke(yourClassInstance, parameters); 
+1
source share

If your class implements an interface, you can make all methods that you like β€œpublic”, but not add them to the interface. In this case, you can access these methods from the test, but not from you.

0
source share

All Articles