Question

Consider the following class

public class Validator {

    boolean startValiadation(UserBean user){  
        //This method is visible inside this package only        
        return validateUser(user);           
    }

    private static boolean validateUser(UserBean user){
        //This method is visible inside this class only  
        boolean result=false;
        //validations here
        return result;
    }
}

Due to security requirement of above method I did code in above way. Now I want to wrote test cases using Junit. But generally a unit test is intended to exercise the public interface of a class or unit. Still I can use reflection to do some thing what I am expecting here. But I want to know is there any other way to achieve my goal?

Was it helpful?

Solution

But generally a unit test is intended to exercise the public interface of a class or unit.

Well, I don't get too dogmatic about that. I find that often you can get much better testing depth if you're willing to be "white box" about it, and test non-public members. There's a sliding scale though - testing private members directly is relatively ugly, but you can test package private methods easily, just by making sure your test is in the same package as the class.

(This approach also encourages package private classes - I find that if you're rigidly sticking to testing just the public API, you often end up getting into the habit of making all classes public and many methods public when actually they should be package private.)

In this case, I would suggest you test via the startValiadation method. Currently that calls validateUser but ignores the result - I would assume that in the real code it calls the method and does something useful with the result, which would be visible from the test. In that case, you can just call startValiadation with various different User objects and assert which ones should be valid.

OTHER TIPS

You don't need reflection. Just put your test class in the same package as this class. It doesn't need to be in the same folder or the same project to do that.

No you have only three choices to test a private method:

  1. If you are in control of the code, then change the access specifier to public just to test the method
  2. Otherwise use reflection.

This may be of your interest:

3 . Use a public method to test your private method.

Don't test this class in isolation. A unit test, at least in the spirit of TDD as envisioned by Kent Beck, is not a test for a single class or method, but is simply a test that cannot have side effects on other tests.

This Validator class is used in other classes within the same package. First write a failing test using the public interface of those classes, then make it pass by implementing the validation. No reflection needed.

If you would test this class in isolation, you would probably mock this class in the other classes and verify that startValiadation() is really called. This has the disadvantage of coupling your test code to your implementation code. I would say: don't do that.

I recently wrote a post about this, at the bottom there's a link to a presentation by Ian Cooper that goes deeper into this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top