0

I'm having some serious difficulties trying to tests functions with arguments in javascript. How do I tests arguments?

This is my function:

NotificationHelper.prototype.addNotificationItems = function(validationErrors) {
        this.get$NotificationItems().html(render('tmpl-NotificationView-notificationItems', {items: validationErrors}))
};

validationErrors is supposed to be an object and the function render renders the handlebar template in html code. It renders a bunch of li in a loop depending on how many properties there are in the object.

My question is what do I need to test for this argument? Do I need to test for all types?

    //Filled object
    notificationHelper.addNotificationItems({Street: 'Veuillez respecter le format requis.'});
    expect($notificationItems.find('li').length).toEqual(1);
    //Empty object
    notificationHelper.addNotificationItems({});
    expect($notificationItems.find('li').length).toEqual(0);
    //Filled array
    notificationHelper.addNotificationItems(['Street', 'Veuillez respecter le format requis.']);
    expect($notificationItems.find('li').length).toEqual(0);
    //Empty array
    notificationHelper.addNotificationItems([]);
    expect($notificationItems.find('li').length).toEqual(0);
    //Undefined
    notificationHelper.addNotificationItems(undefined);
    expect($notificationItems.find('li').length).toEqual(0);
    //Null
    notificationHelper.addNotificationItems(null);
    expect($notificationItems.find('li').length).toEqual(0);
    //Boolean
    notificationHelper.addNotificationItems(true);
    expect($notificationItems.find('li').length).toEqual(0);
    //Integer
    notificationHelper.addNotificationItems(0);
    expect($notificationItems.find('li').length).toEqual(0);
    //String
    notificationHelper.addNotificationItems('String');
    expect($notificationItems.find('li').length).toEqual(0);

Or do I only make my function accept an object argument:

NotificationHelper.prototype.addNotificationItems = function(validationErrors) {    
    if(typeof validationErrors == Object)
        this.get$NotificationItems().html(render('tmpl-NotificationView-notificationItems', {items: validationErrors}))
    };

As you can see, I am lost... Also is this the good way to do it? Should I throw an error in the function if it's not the good type, instead of just checking it does not have the good behaviour?

5
  • 1
    Just so it's said... Why doesn't your notificationHelper have its own $notificationItems property? Commented Dec 20, 2013 at 16:50
  • It does: $notificationItems = notificationHelper.get$NotificationItems(); Commented Dec 20, 2013 at 16:51
  • Well it's true that it's not it's property, get$NotificationItems() always goes in the DOM to fetch the element, I might change that. Commented Dec 20, 2013 at 16:52
  • 1
    Probably should, unless you're passing in a selector or something when you create it. Having the property already there makes it easier to have two notification areas at once. Also simplifies testing, as you can swap in an object that can tell you exactly what HTML was inserted, not just how the DOM stuff interpreted it. Commented Dec 20, 2013 at 16:54
  • Ok thanks :) What about my question now ^^ Commented Dec 20, 2013 at 16:56

1 Answer 1

2

I'd say, test that the function behaves as specified. No more, no less.

If you specify that certain things will happen if you have wacky input, then you need to test with wacky input just to verify that what you've said is true. It is literally impossible to try every case, though. (Even if you only accept objects...did you try { stuff: { probably: 'wrong' }}? What about new String('heh')?) So you have to be picky about what you'll test, or you'll be at it forever.

I'd recommend*:

  • at least two correct inputs (the reason for two is to eliminate the return 42;-type stubs);
  • two wrong-but-plausible inputs (eg: undefined and an array), and
  • two WTF inputs (maybe 'oops' and the object mentioned earlier).

If a function passes with those inputs, then you can be reasonably confident that other weirdness will trigger the proper response.

* OK. I lied. I wouldn't really recommend any of that stuff. But if you've already said what your function will do, then you have to make sure it does that.

I personally would test only that the function behaves properly when presented with correct input. Then again, though, i make a habit of not specifying what'll happen if the caller can't follow simple instructions. (That gives me the right to whack people with a 2x4 cluestick when they try to tell me that foo.thisClearlyWantsObjects('Im just learned js in 24 hours I like cheese') doesn't work. At least, that's what i'll argue at the trial. I'm confident no jury of my peers would convict me.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.