Arif Muni
Arif Muni

Reputation: 29

how can I access a private method from the test class

I have some methods which are private in the class example and I want to use them in the test class for testing purposes, how can I access these methods and leave them as private

import java.util.*;

public class Example
{
      Scanner scanner;
    public Example()
    {
       scanner = new Scanner(System.in);
    }
    private void enterName()
    {
        System.out.println("Enter name");
        String name = scanner.nextLine();
        System.out.println("Your name is: " + name);
    }
    private void enterAge()
    {
         System.out.println("Enter age");
        int age = scanner.nextInt();
        System.out.println("Your age is : " + age); 
    }
    public void userInput()
    {
        enterAge();
        enterName();
    }
}


public class Test
{

  public static void main(String args[])
  {
      Example n = new Example();
      n.enterName();
      n.enterAge();
    }

}

Upvotes: 0

Views: 397

Answers (2)

Aurelien Ribon
Aurelien Ribon

Reputation: 7634

Unit-testing is indeed black-box testing, so you cannot, and should not, access the private (inner mechanisms) methods. However, white-box testing is often called assertion-based verification. Just put assertions (or it-then-throw statements) everywhere, and your black-box unit test will become a white-box test.

More specifically, try to put pre-conditions and post-conditions as much as possible in your private methods to verify the inputs and the outputs. Therefore, you define a contract between every method caller and callee. If something goes wrong, you'll quickly see where and why.

See Design-by-Contract for more info!

Upvotes: 0

Bart
Bart

Reputation: 17361

Why would you test the private methods while one will only use the public one? Unit testing is about testing for expected behavior. Public methods expose that behavior.

If you want to test the output generated you could implement a protected method to write to out e.g.

public class Example {

    // code omitted 

    private void enterName() {
        writeMessage("Enter name");
        String name = scanner.nextLine();
        writeMessage("Your name is: " + name);
    }

    protected void writeMessage(String msg) {
        System.out.println(msg);
    }
}

In your test you could then create a private class which extends Example and overrides the writeMessage method.

public class ExampleTest {

    public testOutput() {
        MyExample e = new MyExample();
        e.userInput();

        String output = e.getOutput();

        // test output string
    }

    private class MyExample extends Example {
        private String output = "";

        public String getOutput() {
            return output;
        }

        @Override
        public void writeMessage(String msg) {
            output += msg;
        }
    }
}

You also might want a setter or constructor which can inject the Scanner object. This will make testing easier since you could then inject a mocked scanner version.

Upvotes: 2

Related Questions