Jasmine is the testing framework. Karma is the test runner. Working with them when writing unit tests is… cool.
Install Karma and How to use Karma
In Angular guide for unit-testing, Karma is a JavaScript command line tool that can be used to spawn a web server which loads your application’s source code and executes your tests. And Jasmine is a behavior driven development framework for JavaScript that has become the most popular choice for testing AngularJS applications. Here is Introduction for Jasmine
The describe function is for grouping related specs. Specs are defined by calling the global Jasmine function it, which, like describe takes a string and a function. Suites and specs can be disabled with the xdescribe and xit functions, respectively.
As the name implies the beforeEach function is called once before each spec in the describe is run and the afterEach function is called once after each spec.
In chapter “Testing a Controller” of Angular Unit Test Developer Guide, it provides a great example.
It is possible to Mock Services by mocking inject or using $injector.
Everytime I start Karma and fails, and edit the spec files, the Karma would shout at me “your files have done a complete reload!”
It’s really annoying (perhaps there are other solutions), so I decided to run with
karma start --single-run
Putting f in front of your it
s or describe
s, and start your Karma.
Only the one you prefixed with f
will run.
To log into console when using Jasmine, use console.log directly.
Install Karma Plugin in WebStorm, and you can now configure that ^R will run the spec code in Karma.
If you would like to prefix f
to your suite, it will just function as handy
as any other Unit Test framework for Python or Ruby.
To run in debug mode, install JetBrains IDE Support Plugin in Chrome, and configure the IDE Connection Host and Port according to what your IDE says.
Some points need attention:
In karma.conf, put controller code’s pass.
To test a function from outside (Jasmine), the function should be defined in $scope. Normal function (can be thought as private?) is not available for testing.
To make a validation function testable, the error message (exception object) should be return.
function save() { ... }
can be change to
$scope.save = function () {
var error = ErrorDialog.validate([
...
if (error) {
return error;
}
}
after that
var controller = $controller('MyCtrller', {
// inject services
});
var error = $scope.save();
expect(error).toBeDefined();
expect(error.code).toEqual('W11');
But some people insist that this is a pollution of namespace. The self.
style should be used instead.
Not a bad idea but not necessary. After the controller is successfully initiated, $scope.save is defined naturally (unless you mistake the function’s name!).
It may be a good idea to extract duplicated codes into a js file just aside the controller testers. After you define functions there, it can be used to other controller testers.
for example, I would like to initialize $scope attributes before every testing, so I may put function
function addAttr(obj, attributes) {
for (var attr in attributes) {
obj[attr] = attributes[attr];
}
}
to a separate js file on the same directory of controller testers.
Written on April 9th, 2017 by Hanezu