Java Testing – Unit Tests for Constructors

javanulltesting

If I make a class, that in the constructor accepts an array or collection, but this array or collection is optional (the parameter can be null), and then I store that collection in the object in question, in the constructor i need something like:

this.coll = coll == null ? null : coll.clone();

Should I unit-test such kind of code? like check if it works when passing null or not?

Best Answer

Technically, what you should test depends on your test goals. But in general, you should try to test everything that can go wrong. Here:

this.coll = coll == null ? null : coll.clone();
  • You might have forgotten to use the coll parameter, i.e. the above statement is missing. This can be checked by a test that depends on the coll provided to the constructor.

  • You might have forgotten to clone the parameter:

    this.coll = coll;
    

    This can be checked by a test that modifies the parameter coll and compares the result with the object-owned coll. They should be different after the modification.

  • You might have forgotten to handle the null case:

    this.coll = coll.clone();
    

    This can be checked by a test that omits this parameter/provides a null value. Usually we'd expect an exception, here a null is OK.

  • Another thing that could go wrong is that you create a null object or default instance when a null is encountered, e.g.:

    this.coll = coll == null ? new Collection() : coll.clone();
    

    If your code is correct, you want to ensure that an actual null here, not a default instance.

That's already four test cases that would be sensible for this simple line of code. Using a code coverage tool can help to detect uncovered cases in your code, in particular if you also look at branch coverage. Some tools have problems with expression-level control-flow (?:, &&, ||) so it's better (and more readable for humans, too!) to use statement-level conditionals:

if (coll != null) {
    coll = coll.clone();
}
this.coll = coll;