0

I have an outer class, Outer, and an inner class, Inner. For testing a public method, outerMethod(), in Outer I need to create an instance of an Inner, which will be stored in a list called inners. The inner class is a modified version of another class, Other.

To overview:

class Other{
    public Other(){
       //doesnt matter actual implementation
    }
}

class Outer{
    private List<Inner> inners = new ArrayList<Inner>();

    public Outer(){}

    public void outerMethod(){}

    private class Inner{
        public Inner(Other other){}
    }
}

My question is should I create a method like the following just for testing purposes.

public void createInnerInstance(Other other)
{
    Inner inner = new Inner(other);
    inners.add(inner);
}

Is there any other workaround for this? Now I can make Inner public but Outer is the only class that really uses Inner.

Regards

eytanfb
  • 443
  • 4
  • 17
  • I am confused. Why do you need an instance of Inner to access a method in Outer class that is already in the outer class from the Outer class itself? What is the need to maintain a list of Inner? Where are you planning to add the createInstance method? – Chetan Kinger Sep 29 '12 at 07:11
  • related [What's the proper way to test a class with private methods using JUnit?](http://stackoverflow.com/questions/34571) – Oleg Mikheev Sep 29 '12 at 17:51

1 Answers1

1

Changing code specifically for testing purposes is probably not a very good idea.

You've got two options - either to redesign your class as @bot suggests in comments, or to apply workarounds.

You could change field/inner class access modifiers and use them from your test instead. Take a look here, and here for implementation details.

Community
  • 1
  • 1
Oleg Mikheev
  • 17,186
  • 14
  • 73
  • 95
  • I would still be changing code where it doesn't make sense. I mean, still no one else but Outer would need Inner. So aren't they kind of the same thing: changing code for testing? – eytanfb Sep 29 '12 at 06:16
  • I disagree. Making your code more testable has an automatic effect of improving the design of your code. Testable code has most properties of well designed code. – Chetan Kinger Sep 29 '12 at 07:06
  • So you agree with Oleg and disapprove with my approach but agree that code could be changed to be more testable? – eytanfb Sep 29 '12 at 08:28
  • eytanfb, you would be changing test and not the code base being tested @bot well designed code is more testable and not the other way round, I have yet to see a well designed code with method's javadoc saying something like _"this method is here just for testing purposes - please don't use it"_ – Oleg Mikheev Sep 29 '12 at 08:34
  • @eyetanfb I don't agree with Oleg. Yes I disagree with you. Refactoring your code to make it more testable is a good thing. That doesn't mean you do stupid things like make an private method public. If your existing code base is not testable, it only indicates that it has not been designed well. I advice you guys to check out the SOLID principles. If I see a class directly instantiation its dependencies within its self, I will change that to use dependency injection and dependency inversion instead. I regret to inform you that you are ill informed. – Chetan Kinger Sep 29 '12 at 11:04
  • I also disagree with your suggestion of using reflection to test private methods. – Chetan Kinger Sep 29 '12 at 11:11
  • @bot you disagree not just with me but with the rest of SO community: [What's the proper way to test a class with private methods using JUnit?](http://stackoverflow.com/questions/34571). – Oleg Mikheev Sep 29 '12 at 17:55
  • You are missing the point. I could go around defining a class with 100 private methods and then go test each method using reflection. The problem here is not private methods. The problem is a badly designed class. Do you really thing the only way to make the code presented by the OP testable is to use reflection and that it would be a bad idea to refactor the code to improve the design and also make the code more testable? – Chetan Kinger Sep 29 '12 at 18:28
  • You are missing the point. I could go around defining a class with 100 private methods and then go test each method using reflection. The problem here is not private methods. The problem is a badly designed class. Do you really thing the only way to make the code presented by the OP testable is to use reflection and that it would be a bad idea to refactor the code to improve the design and also make the code more testable? Reflection makes sense when you have legacy code. If you are starting out fresh with a class you have control over, design it well so it is testable. I wish you comprehend! – Chetan Kinger Sep 29 '12 at 18:36
  • 1
    And FYI, the SO community agrees with me. You need to read the question that you linked me to once again. Make sure you read all the answers and the comments to the question you linked me to because it resonates my views exactly and not yours. – Chetan Kinger Sep 29 '12 at 18:38
  • ok, community agrees with you but votes to use reflection, let's put it this way – Oleg Mikheev Sep 29 '12 at 19:36
  • well thank you to you both guys. this is a great conversation for me to learn from. and although I forgot to tag it, this was part of a homework, and this code was kind of given to me, so you could say its legacy code. – eytanfb Sep 30 '12 at 06:17