Tags | unit-testing bdd jasmine |
Jasmine is a unit testing framework we like a lot. Technically it’s a Behavior Driven Development (BDD) framework.
There are a few different ways to get started with Jasmine. Let’s go with the technically simplest one first:
Download the latest Jasmine release from here: https://github.com/jasmine/jasmine/releases. Unzip the stuff. Now replace the src with your own code and replace the specs with your own tests.
Edit index.html
so that it refers to your code.
To run the tests just open index.html
in your browser.
Open up a terminal. Now execute each of the following commands:
mkdir my_jasmine_goodies
cd my_jasmine_goodies
npm init
npm add jasmine
npx jasmine init
npx jasmine examples
Take a moment to Google npm and npx if these concepts are new to you.
Now, in your editor of choice (vscode, subline, atom…), open up package.json
. There should be something that looks like this:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
Edit it to look like this:
"scripts": {
"test": "jasmine"
},
To run your tests you can now just do this:
npm test
Base your project structure on the example code that jasmine created for you.
Now that you have the basics down, here are a few more advanced ways to use Jasmine.
Say you have some code that does some DOM manipulation. Some tools exist that make this pretty straightforward.
npm add jsdom
Now
var jsdom = require("jsdom");
function winning() {
// This is the function under test. Put it somewhere that makes sense and "require" it here
document.getElementById("booya").innerHTML = "so cool";
}
describe("FooFighters", function() {
beforeEach(function() {
// make a fake DOM to interact with
const dom = new jsdom.JSDOM('<html><body id="booya">initial</body></html>');
global.document = dom.window.document;
global.window = dom.window;
global.navigator = dom.window.navigator;
});
it("updates dom", function() {
expect(global.document.getElementById("booya").innerHTML).toBe("initial");
winning(); // call the function that updates the dom
expect(global.document.getElementById("booya").innerHTML).toBe("so cool");
});
});
Spies (often referred to as mocks in other languages and tools) are used to allow a kind of dependency injection within your tests. Here is a basic example of how it works:
class Thing {
constructor() {
this.a = "some initial value";
}
setA(newA) {
this.a = newA;
}
}
describe("Spies", function() {
it("doesn't do surprising things", function() {
var o = new.Thing();
expect(o.a).toBe("some initial value");
o.setA("x");
expect(o.a).toBe("x");
});
it("mocks", function() {
var o = new Thing();
spyOn(o, "setA"); // spy on the function
expect(o.a).toBe("some initial value");
o.setA("x"); // o.setA has been replaced with a spy
o.setA("x");
o.setA("x");
o.setA("x");
expect(o.setA).toHaveBeenCalledTimes(4);
// we can check how many times it was called.
// we can even check what arguments were passed to this function
// setA now has no side effect
expect(o.a).toBe(1);
});
});
Of course, this is just the tip of the iceberg. But it gives a basic intro. Spies are detailed in the official tutorial.
Use this. The official docs are nice.
https://github.com/tschaub/mock-fs
Sometimes you’ll want to make sure that click events are fired as and when they should be. The following resources should help with that:
..* (A brief introduction to unit testing.)
Should the embedded slides not load, you can access the presentation here
..* (A brief introduction to Jasmine)
Should the embedded slides not load, you can access the presentation here.