Jasmine - Atileon/OC-p8 GitHub Wiki
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.
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:
- describe(description,specDefinitions) Create a group of specs. This section is often called "suite" . Calls to describe can be nested within other calls to compose your suite as a tree
Name | Type | Description |
---|---|---|
description | String | Textual Description of the group |
specDefinitions | function | Function for Jasmine to invoke that will define inner suites and specs |
- it(description, testFunction, timeout) Define a single spec. A spec should contain one or more expectations that test the state of the code.
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. |
- expect(actual) ->{Matchers}
Create an expectation for a spec.
Name | Type | Description |
---|---|---|
actual | Object | Actual computed value to test expectations against. |
└── 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);
});
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:
Go to Top -------/-------/------- Next page(The App)