adams.co.tt

jasmine-underscore

19th June 2011

I love Jasmine. It’s a fantastic testing framework with a good set of extensions (e.g. jasmine-jquery).

I also love Underscore. It has a number of utility functions that help improve the readability of my code and dramatically reduces the code duplication associated with managing collections in JavaScript.

Recently I’ve been using Jasmine and Underscore together in tests. Underscore provides a number of functions to interrogate the state of an object, and I find I often use these in my Jasmine specs:

it('should return today as a date', function () {
  var cal = new AwesomeCalendar();
  expect(_(cal.today()).isDate()).toBeTruthy();
});

This is a useful test, however it doesn’t read quite as nicely as it could. There is a lot of noise, and the failure reporting won’t be particularly informative. With that in mind I created jasmine-underscore. This extension creates matchers for Jasmine based on the Underscore’s object functions. Any function that Underscore provides that has the ‘is’ prefix can be used as a matcher. For example, the test above becomes:

it('should return today as a date', function () {
  var cal = new AwesomeCalendar();
  expect(cal.today()).toBeDate();
});

This is not only more readable, it also produces better failure messages. The first spec’s error message would be Expected false to be truthy. Now the failure will read Expected null to be date if today unexpectedly returns null.

using

Another situation I found myself using Underscore with Jasmine a great deal is the generation of examples for specs:

_([
    [1, 2, 3], 
    [2, 3, 5]
  ]).each(function (vals) {

  var first = vals[0];
  var second = vals[1];
  var total = vals[2];

  it('should sum ' + first + ' and ' + second, function () {
      expect(sum(first, second)).toEqual(total);
  });
});

Again, this somewhat noisy, and could read somewhat better. The jasmine-underscore extension provides the using function. It is backed by Underscore and helps generate test examples in a meaningful way:

using([1, 2, 3], [2, 3, 5], function (first, second, total) {
  it('should sum ' + first + ' and ' + second, function () {
      expect(sum(first, second)).toEqual(total);
  });
});
blog comments powered by Disqus