-3

I am testing a class that looks like the example below, using JunitTesting.

 public RandomObject MainMethod(int id) {
       RandomObject o = dBconn.getRandomObject(id);
       subMethod(o);

       //also calling other private methods here

       return o;

 }

 private subMethod(RandomObject o) {
        //Do something random here

 }

I have three choices:

  1. Only test my MainMethod(), but then I must access DB by hardcoding DB-values into my test.
  2. I can avoid testing MainMethod() and only test the subMethod, but then I must make my private methods public.
  3. Do both 1 and 2.

What is best practice?

TorK
  • 567
  • 2
  • 10
  • 27
  • possible duplicate of [How to Unit Test without testing private methods calling database](http://stackoverflow.com/questions/27268502/how-to-unit-test-without-testing-private-methods-calling-database) – Raedwald Feb 18 '15 at 19:48
  • I am sorry and you are correct, it is a very similar question. But the answers in here was better (in my case at least), than the answers in the other thread. What should I do? Keep this question or delete this question? I have recieved a suitable answer, so I don't care if I delete this :) – TorK Feb 19 '15 at 08:04

2 Answers2

1

The best practice when doing JUnit tests is to write your JUnit tests under the same package as the class that you are testing. If you do that, you can keep your methods with package visibility and still test them. Package visibility is the default visibility of a method when no visibility modifier such as private, protected or public is specified.

Jadiel de Armas
  • 8,405
  • 7
  • 46
  • 62
  • That is true, but this is a large existing system. It would be messy to have tests and classes in same package (atleast I would prefer not to change it) – TorK Feb 18 '15 at 16:01
  • 2
    @tork The test classes don't literally have to be in the same directory as the real classes. You can use a separate directory tree for your test classes. Maven projects e.g. organize code into `src/main/java` and `src/test/java`, for example. – Kenster Feb 18 '15 at 18:12
  • @tork What Kenster says is true. You can have classes in the same package that are not in the same folder. – Jadiel de Armas Feb 18 '15 at 18:20
  • Thank you for your answers. The system-structure was generated years ago. They put classes in one package and tests in another. Guess it is to keep tests together, and to be able to run all tests at once local (they also run in jenkins) I think I will go for the answer of making the methods protected. – TorK Feb 19 '15 at 07:57
1

A few options spring to mind.

I've worked on projects where utility methods are used in order to execute private methods by reflection is the preferred choice.

In other projects, I've seen certain developers change the access modifier of subMethod to protected. Then, inside your test class, define an inner class inherits the class you're testing. This facade can then define a public method that you can call in your test. Something like:

private class RandomObjectFacade extends RandomObject {

    public void subMethodFacade(RandomObject o){
         super.subMethod(o);
    } 
}

It depends on what you think is best. Whether you want to put up with the fragility / performance penalty of reflection or make small, intrusive changes to the existing code - changing the access modifier may not be appropriate in your scenario.

Mike
  • 91
  • 6
  • Thank you for your answer. This is what I will go for. However, I don't feel too comfortable by making the classes protected instead of private. I do not like that they can be accessed by other classes in the same package (most of the systems code is in that package) – TorK Feb 19 '15 at 08:00