Friday, November 4, 2016

Testing private methods using Reflection

- What about testing private methods ? 
- Hum... You can't because they're private dummy.
- And what about using reflection to make them accessible ?

Because we don't have access to private methods, we generally don't test them. This can be a weakness in your testing strategy. Private methods are usually a very sensible part of your code. I've have seen a lot of developers modifying the visibility of their code from private to protected. That's a bad practice. Don't change the visibility of your code for testing purposes.

A solution consists of using reflection to make these private methods accessible for testing. 

I really don't like to use reflexion in my application code because if someone is doing some refactoring like renaming a method and forget to update the reflexive code part, you will get a very bad runtime exception. If it is possible to perform an operation without using reflection, then it is preferable to avoid using it.

Test code is not application code. Your tests does not go into production, that's why I'm not afraid of using reflection in my test classes. 

Here's an example :

MyClass.java
public class MyClass {
 
  private String myPrivateMethod(Long id) {
    //Do something private
    return "SomeString_" + id;
  }
}

MyClassTest.java
import java.lang.reflect.Method;

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

public class MyClassTest {
 
  private MyClass underTest;

  @Test
  public void testMyPrivateMethod() throws Exception {

    underTest = new MyClass();
  
    Class[] parameterTypes = new Class[1];
    parameterTypes[0] = java.lang.Long.class;
  
    Method m = underTest.getClass().getDeclaredMethod("myPrivateMethod", parameterTypes);
    m.setAccessible(true);
  
    Object[] parameters = new Object[1];
    parameters[0] = 5569L;
  
    String result = (String) m.invoke(underTest, parameters); 
  
    //Do your assertions
    assertNotNull(result);
  }
}
Resource Link: 
http://onjavahell.blogspot.com/2009/05/testing-private-methods-using.html

No comments:

Post a Comment