W3docs

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

To test a class that has private methods, fields, or inner classes, you can do the following:

To test a class that has private methods, fields, or inner classes, you can do the following:

  1. Write package-private or protected methods in the class that call the private methods, fields, or inner classes, and use those methods to test the private ones.
  2. Use reflection to access the private methods, fields, or inner classes and test them directly.

Note: Directly testing private members is often discouraged in unit testing. It is generally better to test the public behavior of your class, as private members are implementation details that may change without affecting the public API. Consider using package-private visibility or refactoring your code to improve testability instead.

Here's an example of how you could test a private method using the first approach:


// Production class
public class MyClass {
   private void privateMethod() {
     // implementation goes here
   }

   // Package-private method for testing
   void testPrivateMethod() {
     privateMethod();
   }
}

// Test class
import org.junit.Test;
import static org.junit.Assert.*;

public class MyClassTest {
   @Test
   public void testPrivateMethod() {
      MyClass myClass = new MyClass();
      myClass.testPrivateMethod();
      // assert the desired behavior of the private method
   }
}

Here's an example of how you could test a private field using the second approach:


// Production class
public class MyClass {
   private int privateField;

   public void setPrivateField(int value) {
      privateField = value;
   }

   public int getPrivateField() {
      return privateField;
   }
}

// Test class
import java.lang.reflect.Field;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class MyClassTest {
   @Test
   public void testPrivateField() throws Exception {
      MyClass myClass = new MyClass();
      Field privateField = MyClass.class.getDeclaredField("privateField");
      privateField.setAccessible(true);
      privateField.set(myClass, 42);
      assertEquals(42, myClass.getPrivateField());
   }
}

I hope this helps! Let me know if you have any other questions.