6

I have a requirement in which I have to invoke a private method of an abstract class.

Let's say the abstract class looks like below:-

public abstract class Base {

    protected abstract String getName();

    private String getHi(String v) {
        return "Hi " + v;
    }
}

Can some let me know is there a way I can call getHi (may be via Reflection or some other means) so that I can test it out? I am using Junit 4.12 and Java 8

I have gone through this question but here the methods are not private in the abstract class.

I have also gone through this question even this one does not talk about private method in abstract class.

I am not asking here whether we should test the private method or not or what is the best strategy for testing private methods. There are lot of resources available in the web regarding this. I am just trying to ask how should we invoke a private method of an abstract class in java.

Community
  • 1
  • 1
tuk
  • 5,941
  • 14
  • 79
  • 162
  • See http://stackoverflow.com/q/105007/3788176 – Andy Turner May 16 '16 at 11:39
  • 1
    I am aware about the discussion whether we should test private method or not. Actually I am interested to know if it is possible to invoke a private method of an abstract class from a test code? – tuk May 16 '16 at 11:45
  • See http://stackoverflow.com/questions/6913325/annotation-to-make-a-private-method-public-only-for-test-classes, which gives some approaches. In particular, [this answer](http://stackoverflow.com/a/6913775/3788176) links to the JUnit doc about testing private methods. – Andy Turner May 16 '16 at 11:47
  • 1
    where is the getHi method used? Its an example but for testing the only alternative here would be to use reflection which is terribly ugly. you can find libraries like PowerMock that can help you but in general its just wrong to have to use such invasive code. For private methods in real life, there is always some form of public, protected or package access methods that you can use before you get to them. Then mostly, mock frameworks are used like Mockito and JMock combined with CDI and IoC. There just isnt a way to get to your specific method without reflection! its not used and its private. – Joao Esperancinha May 16 '16 at 12:29
  • You can, but you _shouldn't._ – Louis Wasserman May 16 '16 at 17:21
  • What you test in unit tests is the behavior of your class. The method in question either does modify the behavior which can be asserted, or doesn't modify the behavior and therefore can be deleted. – Mifeet May 16 '16 at 19:00
  • 1
    More about this issue [here](http://stackoverflow.com/q/34571/2032064) and [here](http://stackoverflow.com/q/7569444/2032064) – Mifeet May 16 '16 at 19:01
  • 1
    I have updated the question about what I am trying to ask & why the two questions you shared and did not satisfy my need. – tuk May 17 '16 at 09:40
  • @Mifeet This was not a duplicate. The other question was not about abstract classes and the answer to the other question does not help in this case (I have the same question as OP). And other suggestions mostly seem to be about how to avoid needing to invoke private methods, which may be wise, but they are not answers. – russell Aug 22 '17 at 22:18

1 Answers1

4

I am able to invoke the private method of an abstract class as follows:-

Let's say I have a class extending the Abstract base class:-

public class Child extends Base {
  protected String getName() {
     return "Hello World";
  }
}

Then I am able to invoke the private method as below:-

Child child = new Child();
try {
        Method method = Base.class.getDeclaredMethod("getHi", String.class);
        method.setAccessible(true);
        String output = (String) method.invoke(child, "Tuk");
        System.out.println(output);
    } catch (Exception e) {
        e.printStackTrace();
    }
tuk
  • 5,941
  • 14
  • 79
  • 162