2

I am Newbie to Java and Junit,

Does Anyone know how to write test cases for private functions in Junit ?

After Some research in Google I setup environment and wrote unit test cases for public functions and mocked parent classes with help of Mock() proxy.

For public function with inline valued arguments, I reached my expectations and tested both Positive and Negative Path.

For Private Methods I followed

How do I test a private function or a class that has private methods, fields or inner classes?

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

And for fields:

Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);

code:

public class universalConfiguration { 
   private Integer getTotalDocuments(Client client, String indexName, String indexType, QueryBuilder searchQueryBuilder) {
    SearchResponse response = client.prepareSearch()
             .setIndices(indexName)
             .setTypes(indexType)
             .setSize(0)
             .setQuery(searchQueryBuilder)
             .execute().actionGet();

     return (int) response.getHits().totalHits;
 }
}

This is My code I want to test this private method with this public class, i tried to use this method using getDeclaredMethod and setAccessible but I am getting errors.

UniversalConfiguration universalConfiguration = new UniversalConfiguration();    
getTotalDocuments getTotalDocuments= universalConfiguration .
                                         getDeclaredMethod(getTotalDocuments,
                                         client,
                                         indexName,
                                         indexType, 
                                         searchQueryBuilder);           
    getTotalDocuments.setAccessible(true);

getTotalDocuments method cannot be resolved to a type

Correct me If i did any mistakes.

Vijay Krishna
  • 112
  • 12
  • 2
    The best answer in the thread you linked is still in the comments, "Best way to test a private method is not testing it directly". – daniu Jun 25 '18 at 06:33
  • please read (and follow) [Java Naming Conventions](http://www.oracle.com/technetwork/java/codeconventions-135099.html) – Timothy Truckle Jun 25 '18 at 21:29

3 Answers3

2

Change your mind about UnitTests: A UnitTest does not test code, it rather tests behavior. It does that by using the public interface of the unit (which is not necessarily, but usually a public method) and verifies the observable behavior which is return values and or communication with dependencies.

private methods are implementation details that may change for refactoring and this is exactly the time when we want our Unittests not to change to guarantee that the desired behavior still exists after the change.

Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
1

You have some issues with your code, please change it to below:

Class universalConfiguration = UniversalConfiguration.class;    
Class[] cArg = new Class[4];
cArg[0] = Client.class;
cArg[1] = String.class;
cArg[2] = String.class;
cArg[3] = QueryBuilder.class;
Method getTotalDocuments = universalConfiguration.                                          getDeclaredMethod(getTotalDocumentCount,cArg);           
    getTotalDocuments.setAccessible(true);
Aman Chhabra
  • 3,824
  • 1
  • 23
  • 39
1

The question is a little opinion biased. However there are two simple ways you can do this:

Test them via a visible method. Change the visibility to default.

Default visibility will enable the methods to be seen/called at a package level (the method is no longer private) this is a very effective methodology, however your method is no longer private.

Testing via another visible method will enable you to get effective test coverage, although the test could be a little less specific.

How best to approach this will heavily depend on the code you are testing.

MartinByers
  • 1,240
  • 1
  • 9
  • 15
  • 1
    This is not a bad answer, and has been downvoted (I believe) because it offers no specific technical guidance. In fact, the difficult part of this problem is not the technical part - you can just change private to public and you've solved that part. So, this answer addresses (or partially addresses) the *hard* part of the problem. Thanks! – Max von Hippel Jul 22 '19 at 22:23