Shared Behaviors in Screw.Unit or how to DRY up your javascript specs

August 28, 2009 Pivotal Labs

The project that I’m working on is using Screw.Unit for Javascript testing. We recently ran into a case where we found ourselves copying and pasting some code. We wanted to DRY up our specs and found a neat way to do it that I figured I’d share with everyone. Here’s a really simple example to demonstrate how we did it.

Given a cat model that keeps track of the number of lives the cat has left:

function Cat() {
    var lives = 9;
    this.die = function(num) {
        lives = lives - 1
    };
    this.lives = function(){
        return lives;
    };
    this.isDead = function() {
        return lives <= 0
    };
}

Lets make up a spec that checks that isDead works for some values of lives:

Screw.Unit(function() {
    describe('Cat', function() {
        var cat;
        describe('isDead', function(){
            var shouldNotBeDeadBehavior = function(num){
                describe("when the cat has " + num + " lives left", function(){
                    it("it should not be dead", function(){
                        cat = new Cat({lives: num});
                        expect(cat.isDead()).to(be_false);
                    });
                });
            }

            for (i=3;i>0;i--){
                shouldNotBeDeadBehavior.call(Screw.Specification, i);
            }

            describe("when the cat has 0 lives left", function(){
                it("it should be dead", function(){
                    cat = new Cat({lives: 0});
                    expect(cat.isDead()).to(be_true);
                });
            });
        });

    });
});

The neat part in here is the line:

shouldNotBeDeadBehavior.call(Screw.Specification, i);

If you’re not familiar with it, the call function in javascript allows you to define what “this” is for that function call. By calling our shared behavior with Screw.Specification, we’re saying that we want to execute this function within the context of the Screw.Unit Specifications. This lets us execute our specs as though they were written in various places. The test results from this spec look like this
screw unit screenshot

This is one way to DRY up some of your Screw.Unit specs. If you find yourself copying and pasting code, consider refactoring the spec out into a shared behavior instead.

Have other good ways to clean up Srew.Unit specs? Share them in the commments!

About the Author

Biography

More Content by Pivotal Labs
Previous
Little, shiny robots
Little, shiny robots

One of my favorite computer games when I was growing up was Robot Odyssey; I imagine it will come as a surp...

Next
Desert 0.5.2 Released
Desert 0.5.2 Released

Desert 0.5.2 focuses on speed improvements and bug bixes. Pivotal Tracker Stories: "Fix mailer templates ...

Enter curious. Exit smarter.

Learn More