Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test void method that only modifies private class member variables?

I'm trying to unit test a method in a class that initializes some private fields:

public void init(Properties props) throws Exception {

    this.language = props.getProperty(Constants.LANGUAGE,Constants.LANGUAGE_DEFAULT);   
    this.country = props.getProperty(Constants.COUNTRY,Constants.COUNTRY_DEFAULT);

        try {
            this.credits = Integer.valueOf(props.getProperty(Constants.CREDITS_OPTION_NAME, Constants.CREDITS_DEFAULT_VALUE));
        } catch (NumberFormatException e) {
            throw new Exception("Invalid configuration: 'credits' does not contain a valid integer value.", e);
        }
        //rest of method removed for sake of simplicity
    }

My dilemma is that I want to assert that the language, country and credits fields have been set after calling init, however they are private with no public accessor methods. I see there are two solutions for testing this:

  1. Make public methods for accessing the private fields, then call these methods after testing the init method.
  2. Make the unit test just call init method, and assume everything worked correctly is no exception was thrown.

What do you think is the ideal way to test this method?

like image 387
James Goodwin Avatar asked Jan 05 '11 12:01

James Goodwin


People also ask

How do you verify a void method?

Using the verify() Method Whenever we mock a void method, we do not expect a return value. That is why we can only verify whether that method is being called or not. Features of verify() : Mockito provides us with a verify() method that lets us verify whether the mock void method is being called or not.

Can we unit test private methods?

Unit Tests Should Only Test Public Methods The short answer is that you shouldn't test private methods directly, but only their effects on the public methods that call them. Unit tests are clients of the object under test, much like the other classes in the code that are dependent on the object.


1 Answers

I want to assert that the language, country and credits fields have been set after calling init

Some philosophy: why do you care whether they are set correctly? If the answer is "so the class then behaves correctly", then you can test that they have been set correctlty by testing that expected subsequent behaviour. If however setting them incorrectly has no effect they are redundant and you should remove them.

Another poster has suggested using reflection to access the private fields. I advise against this; anything marked private should be an implementation detail of the class, and therefore should not be directly tested. You should instead test the published API of your class. You then have the freedom to refactor it easilly by changing implementation (private) details.

like image 59
Raedwald Avatar answered Oct 06 '22 01:10

Raedwald