简体   繁体   中英

Generic way to unit-test that all Collections can not be null

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?

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.

You can generate the tests using reflection. eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM