3

I often create objects that contain some kind of Collection (Set, List, whatever). They can never be null. If null is passed by constructor or setter, then new instance of empty collection is created. Here is an example with error (marked by comments).

package com.myapp;

import com.google.common.collect.Lists;

import java.util.List;

public class MyClass {
    private List<String> myNeverNullList1;
    private List<String> myNeverNullList2;

    public MyClass(List<String> myNeverNullList1, List<String> myNeverNullList2) {

        this.myNeverNullList1 = myNeverNullList1==null? Lists.newArrayList():myNeverNullList1;
        this.myNeverNullList2 = myNeverNullList2==null? Lists.newArrayList():myNeverNullList2;
    }

    public void setMyNeverNullList1(List<String> myNeverNullList1) {
        this.myNeverNullList1 = myNeverNullList1==null? Lists.newArrayList():myNeverNullList1;
    }

    public void setMyNeverNullList2(List<String> myNeverNullList2) {
        //OOPS, I forgot to put the null check here, should be caught by Unit Tests
        this.myNeverNullList2 = myNeverNullList2;
    }
}

I test this behavior in unit tests by unit tests, but it is tedious to write such simple test for each collection. Is there any library, that would help me to test this kind behavior automatically?

Michal Krasny
  • 5,434
  • 7
  • 36
  • 64
  • this might help you. http://stackoverflow.com/questions/11152536/check-if-a-collection-is-empty-in-java-which-is-the-best-method – KhAn SaAb Aug 25 '16 at 12:11
  • You need to test all of your units separately, so long story short - no, there's no generic way that verifies all of your collections in your application that are not null. If you have 2 or N collections that need to be verified, you need to write 2 or N assertions. – Royal Bg Aug 25 '16 at 12:12
  • Do you really need to replace the whole list ? It seems very dangerous to me according to the possible side-effects of such an operation... – Spotted Aug 25 '16 at 13:27
  • I'd rather use static null checking in my IDE (eclipse in my case) and annotate the parameters to the constructor and the setters with javax.validation.constraints.NotNull. – mtj Aug 25 '16 at 13:47

2 Answers2

2

The generic answer would be: make your field final and do not allow to set it later on. Then the compiler does all that checking for you. In other words: make your policy that objects are immutable by default; and only deviate from that policy if you have very good reasons.

If there are good reasons to have multiple "set-able" lists in your class (which honestly: I can't think of) then the next best thing would be to write a "test-only" reflection utility which uses reflection to acquire all list/collection fields that have a matching setter ... to first call the setter with null and to then check that the field isn't null.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
1

You can generate the tests using reflection. e.g. you can have a list of classes, examine the constructors and instance methods looking for collections on setters and check they behave as expected when you pass a null value. Once you have written the tests, all you need is a list of all the classes this check should be applied to.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130