Skip to content
tdkehoe edited this page Sep 15, 2015 · 23 revisions

#Initialization and directory structure

In the project root directory, run

jasmine init

This creates two directories and a file:

spec/support/jasmine.json

Next, create two files:

touch spec/spec.js
touch app.js

If your app uses a Constructor function, name the filename to match the Constructor, e.g., car.js.

The directory should now look like:

spec/support/jasmine.json
spec/spec.js
app.js

#app.js app.js is an object of keys and methods. The name of the object is module.exports.

module.exports = {
  helloWorld: function() {
    console.log("Connected!");
    return "Hello world.";
  },
  addOne: function(num) {
    return num + 1;
  },
  upperCASE: function(arr) {
    var hold = [];
    for (var i = 0; i < arr.length; i++) {
        hold.push(arr[i].toUpperCase());
    }
    return hold;
  }
};

The line console.log("Connected!"); will indicate whether spec.js and app.js are hooked up.

Each method must return something. The name of the returned variable doesn't matter.

Constructor Functions

With a Constructor function, define the Constructor on the first line. The first line can be any of the following:

var Car = function (mpg) {
function Car (mpg) {
var Car = function Car (mpg) {

The latter is very clear. Capitalize the Constructor.

Include arguments to pass through from calling the function.

Then on the last line set module.exports equal to the Constructor"

module.exports = Car;

###Properties of Constructors

Declare properties in the Constructor, using this:

this.model = model;
this.gallons = 0;

The Constructor is a function, not an object, so it uses = and ; instead of : and ,.

this refers to the Constructor, similar to self in Ruby. It's better than saying Car.model = model; etc.(Why?)

Values passed in as arguments are declared as properties, in the format this.arg = arg.

Values that are declared instead of passed in are just declared, e.g., this.value = 25.

###Methods of Constructors

There are two ways to include a method in a Constructor function. It can be defined in the declaration:

var Car = function Car (mpg) {
  this.gallons = 0;
  this.fill = function (gallons) {
    this.gallons += gallons;
  };
};

module.exports = Car;

This is simple and clear but has problems with inheritance. Inheritance works better if the method is declared outside the Constructor function, using prototype and the Constructor name instead of this:

var Car = function Car (mpg) {
  this.gallons = 0;
};

Car.prototype.fill = function (gallons) {
  this.gallons += gallons;
};

module.exports = Car;

prototype is a method on every object. It enables inheritance.

What's the difference between Car.fill and Car.prototype.fill?

#spec.js

The Jasmine keywords are describe, it, xit, expect, and toEqual.

In spec.js:

var app = require('./../app.js');

describe('Test helloWorld', function() {
  it('Hello world test', function() {
    expect(app.helloWorld())
    .toEqual("Hello world.");
  });
});

describe('Test addOne', function() {
  it('Adds one to a number', function() {
    expect(app.addOne(1))
    .toEqual(2);
  });
});

var colors = ['red', 'green', 'blue'];

describe('Test upperCASE', function() {
  xit('Make uppercase', function() {
    expect(app.upperCASE(colors))
    .toEqual(['RED', 'GREEN', 'BLUE']);
  });
});

You can write the test on one line:

    expect(app.nameOfTest(inputData)).toEqual(outputData);

However, the nested parentheses can be confusing. Breaking this into two lines makes the parentheses more clear. If you get the error message "undefined is not a function" on this line, then you may have a parentheses nesting problem.

xit comments out a test. Remove the x to run the test.

##Constructor Function Testing

To reduce confusion, make the first part of the first line of the test match the first part of the first line of app.js:

var Car =

Then put in require and the path:

var Car = require('../car');

The path goes to the app.js file.

#Run jasmine Run the tests from the root directory with the command

jasmine

##Nested Functions

If you're testing methods of a Constructor function/object/class then next the methods in the Constructor function:

var Car = require('./../car.js');

describe('Car', function() {

  describe('car.fill', function() {
    it("gives the car gas", function() {
      var car = new Car(10);
      expect(car.gallons).toEqual(0);

      car.fill(5);
      expect(car.gallons).toEqual(5);

      car.fill(6);
      expect(car.gallons).toEqual(11);
    });
  });

});

###New Instance of Constructor

In the test, create a new instance of the Constructor class/object/function:

var car = new Car("Honda Civic", 1992, 10);

These arguments could represent the make and model, the year, and the mpg.

Then call a method of the Constructor:

car.fill(5);

or

console.log(car.fill(5));

The argument could represent the gallons to fill the car.

In the expect declaration, use methods of the Constructor:

expect(car.gallons).toEqual(5)
Clone this wiki locally