Search code examples
javajunitmockitopowermockito

Instantiating a Class with private constructor using Java/Mockito/PowerMockito


I am writing a test case using JUnit and the method under test takes a final class with a private constructor as a parameter. Since I cannot instantiate it with the new keyword I tried using Mockito but found out that Mockito doesn't like final class. I went to use PowerMockito which seemed reasonable to me but PowerMockito.mockStatic(Field.class); is a void method and I need a reference of Field so that I can pass it as an argument while invoking the method.

I want to catch IllegalArgumentException but first I need to pass reference of Field as an argument

Method under test

public boolean accept(Field field) { 
    if( ignoreNulls ) {
        try {
            if( field.get( super.getObject() ) == null ) {
                return false;
            }
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        }
    }

    return super.accept(field); 
} 

JUnit test case

   @Test(expected=IllegalArgumentException.class)
    public void testAccept() throws Exception {
      DefaultToStringBuilder builder = new DefaultToStringBuilder(new Object());
      PowerMockito.mockStatic(Field.class);

      builder.accept(?);
}

I am not sure how should I be doing this.

Thanks in advance


Solution

  • We can actually use Core Java to achieve this. Code below shows how to do it.

        private Field field;
    
        @Test(expected=IllegalArgumentException.class)
        public void testAccept() throws Exception {
          Class<?> clazz = Field.class;
          Constructor<?> [] constructors = clazz.getDeclaredConstructors();
    
          for(Constructor cons: constructors) {
              cons.setAccessible(true);
              field = (Field) cons.newInstance();
          }
    
          DefaultToStringBuilder builder = new DefaultToStringBuilder(new Object());
          builder.accept(field);
    
          assertNotNull(builder);
        }