Jasmine - Atileon/OC-p8 Wiki

BDD/TDD

Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests.

Source

The Tests Process

So, the tests follow the next process:

describe("A suite is just a function", function() {
  var a;

  it("and so is a spec", function() {
    a = true;

    expect(a).toBe(true);
  });
});

Where:

Name Type Description
description String Textual Description of the group
specDefinitions function Function for Jasmine to invoke that will define inner suites and specs

A spec whose expectations all succeed will be passing and a spec with any failures will fail.

Name Type Attributes Default Description
description String Textual description of what this spec is checking
testFunction implementationCallback <optional> Function that contains the code of your test. If not provided the test will be pending.
timeout Int <optional> jasmine.DEFAULT_TIMEOUT_INTERVAL Custom timeout for an async spec.

Create an expectation for a spec.

Name Type Description
actual Object Actual computed value to test expectations against.

Mocking Our Modules

└── test
   ├── ControllerSpec.js
   └── SpecRunner.html

How show the code above, the Test folder contains the file where we gonna do tests (ControllerSpec.js) so for our case there was created a Mock of our app to be tested, whitin the main Suite

var subject, model, view;
   //Emulates Our Model
  var setUpModel = function(todos) {
    model.read.and.callFake(function(query, callback) {
      callback = callback || query;
      callback(todos);
    });

    model.getCount.and.callFake(function(callback) {
      var todoCounts = {
        active: todos.filter(function(todo) {
          return !todo.completed;
        }).length,
        completed: todos.filter(function(todo) {
          return !!todo.completed;
        }).length,
        total: todos.length
      };

      callback(todoCounts);
    });

    model.remove.and.callFake(function(id, callback) {
      callback();
    });

    model.create.and.callFake(function(title, callback) {
      callback();
    });

    model.update.and.callFake(function(id, updateData, callback) {
      callback();
    });
  };
   // This Emulates Our View
  var createViewStub = function() {
    var eventRegistry = {};
    return {
      render: jasmine.createSpy("render"),
      bind: function(event, handler) {
        eventRegistry[event] = handler;
      },
      trigger: function(event, parameter) {
        eventRegistry[event](parameter);
      }
    };
  };

Thus we create into a beforeEach() function which will call at every single spec the inner function

beforeEach(function() {
    model = jasmine.createSpyObj("model", [
      "read",
      "getCount",
      "remove",
      "create",
      "update"
    ]);
    view = createViewStub();
    subject = new app.Controller(model, view);
  });

Example test

So, let see one little example:

it("should show entries on start-up", function() {
    //Given all TODOS: active or completed
    let todos = [
      { title: "first todo", completed: true },
      { title: "second todo ", completed: false }
    ];
    // setup the model
    setUpModel(todos);
    //passing an empty string('') on setView method indicates that it's the first page
    subject.setView("");

    //Then the application show the entries at startup
    expect(view.render).toHaveBeenCalledWith("showEntries", todos);
  });

So, once you run the SpecRunner.html , the result is:

success

Go to Top -------/-------/------- Next page(The App)