Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How important is checking for bad parameters when unit testing?

Let's say I've got a method that takes some arguments and stores them as instance variables. If one of them is null, some code later on is going to crash. Would you modify the method to throw an exception if null arguments are provided and add unit tests to check that or not? If I do, it's slightly more complicated since javascript has many bad values (null, undefined, NaN, etc.) and since it has dynamic typing, I can't even check if the right kind of object was passed in.

like image 562
swampsjohn Avatar asked Jul 14 '09 23:07

swampsjohn


3 Answers

I think it really depends on what sort of API you're unit testing. If this is a component designed and built for internal use only, and you know usage will be under certain constraints, it can be overkill to unit test for bad parameters. On the other hand, if you're talking about something for distribution externally, or which is used in a wide variety of situations, some of which are hard to predict, yes, checking for bad parameters is appropriate. It all depends on usage.

like image 194
Paul Sonier Avatar answered Oct 12 '22 18:10

Paul Sonier


I think you really have 2 different questions here.

The first is what is the best practice for parameter input validation and the second is should your unit test handle test for these situations.

I would recommend that you either throw an Argument Exception for the parameter that was not supplied correctly to your function or some other variable/message that informs the calling function/user of the situation. Normally, you do not want to throw exceptions and should try to prevent the functions from even being called when you know they will fail.

For your unit test, you should definitely include NULL value tests to make sure a graceful result occurs.

like image 26
RSolberg Avatar answered Oct 12 '22 17:10

RSolberg


JavaScript has instanceof and typeof that can help you check what kind of objects are being passed to your functions:

'undefined' == typeof noVariable; // true
var noVariable = null;
'undefined' == typeof noVariable; // false
typeof noVariable; // 'object'
noVariable === null; // true

var myArray = [];
typeof myArray; // 'object'
myArray instanceof Object; // true
myArray instanceof Array; // true

var myObject = {};
typeof myObject; // 'object'
myObject instanceof Object; // true
myObject instanceof Array; // false

You can use these to set some default "bad" values for your instance variables:

function myFunction(foo,bar) {
    foo = foo instanceof Array ? foo : []; // If 'foo' is not an array, make it an empty one
    bar = bar instanceof Number ? bar : 0;

    // This loop should always exit without error, although it may never do a single iteration
    for (var i=0; i<foo.length; i++) {
        console.log(foo[i]);
    }

    // Should never fail
    bar++;
}

The or operator is also very useful:

function myFunction(blat) {
    var blat = blat||null; // If 'blat' is 0, '', undefined, NaN, or null, force it to be null

    // You can be sure that 'blat' will be at least *some* kind of object inside this block
    if (null!==blat) {
    }
}
like image 39
shuckster Avatar answered Oct 12 '22 16:10

shuckster