Skip to content

Instantly share code, notes, and snippets.

@teyc
Last active January 23, 2016 01:31
Show Gist options
  • Select an option

  • Save teyc/807e2329bce334401d61 to your computer and use it in GitHub Desktop.

Select an option

Save teyc/807e2329bce334401d61 to your computer and use it in GitHub Desktop.
Angular.js testing on the command line

This is a basic worked example of how you can test angular applications that doesn't require a browser, just through a console.

Installation and configuration

C:\temp> npm install
C:\temp> mkdir spec\support
C:\temp> echo {} > spec\support\jasmine.json

Usage:

C:\temp> node_modules\.bin\jasmine testsuite.js
C:\temp> node_modules\.bin\jasmine test-http.js

Expected output:

Started
....


4 specs, 0 failures
Finished in 0.028 seconds

Unpacking the example

npm install reads package.json and installs angular, angular-mocks, jsdom and jasmine.

test-helper.js loads jsdom and sets some global variables necessary to simulate a web browser.

app.js is the angular application that we wish to test.

Controllers and dependency injection

Injecting controllers is a bit of a pain because the angular.mock.inject function is not aware of controller registrations. Instead, a factory function inconveniently named $controller has to be used to construct a controller. Luckily we only need to manually inject $scope. The $controller function will inject other dependencies for us.

See: createController().

Injection of other angular ideas like service, constant, value in contrast is extremely straightforward. For instance, angular.mock.inject(_pi_) injects something that's registered as pi. Alternatively, I noticed that angular.mock.inject(pi) also works just as well.

You can also mock out existing registrations by getting a reference to $provide and calling $provide.provider with a function that returns a new provider. See the example where I replaced 3.141459 with 42.

(function(angular) {
angular.module("app", [])
.value("pi", 3.14159)
.controller("MyController", function ($scope, $http, pi) {
var vm = this;
$scope.firstName = "Sperry";
this.greet = "Hello";
vm.calculateCircumference = function (radius) {
return 2 * pi * radius;
}
vm.getCustomers = function () {
return $http.get("/api/customers");
}
return this;
});
} (angular));
{
"name": "ngmock",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"angular": "^1.4.9",
"angular-mocks": "^1.4.9",
"jasmine": "^2.4.1",
"jsdom": "^7.2.2"
}
}
var jsdom = require('jsdom').jsdom;
global.document = jsdom('<html><head><script></script></head><body></body></html>');
global.window = global.document.defaultView;
global.navigator = window.navigator = {};
global.Node = window.Node;
global.window.mocha = {};
global.window.beforeEach = beforeEach;
global.window.afterEach = afterEach;
/*
* Only for Bower users
*/
//require('../bower_components/angular');
//require('../bower_components/angular-mocks');
/*
* Only for NPM users
*/
require('angular/angular');
require('angular-mocks');
global.angular = window.angular;
global.inject = global.angular.mock.inject;
global.ngModule = global.angular.mock.module;
require("./test-helper.js");
require("./app.js");
describe("Sample test", function() {
beforeEach(angular.mock.module("app"));
it("Can call web service", angular.mock.inject(function($controller, $injector) {
var $httpBackend = $injector.get('$httpBackend');
$httpBackend.when('GET', '/api/customers')
.respond([
{ name: "Mary Jo" },
{ name: "Peter Grimes" }
]);
var myController = $controller("MyController", {$scope : {}});
myController.getCustomers()
.then(function(response) {
expect(response.data.length).toBe(2);
});
$httpBackend.flush();
}));
});
/**
* Minimal example of Angular testing from the
* command-line
*
* C:\temp> npm install
* C:\temp> mkdir spec\support
* C:\temp> echo {} > spec/support/jasmine.json
* C:\temp> node_modules\.bin\jasmine testsuite.js
* Started
* ....
*
*
* 4 specs, 0 failures
* Finished in 0.027 seconds
**/
require("./test-helper.js");
require("./app.js");
describe("Sample test", function() {
beforeEach(angular.mock.module("app"));
var $scope = { };
it("Can test controller's $scope", angular.mock.inject(function($controller) {
var myController = createController($controller);
expect($scope.firstName).toBe("Sperry");
}));
it("Can test controller as vm", angular.mock.inject(function($controller) {
var myController = createController($controller);
expect(myController.greet).toBe("Hello");
}));
it("Can test values", angular.mock.inject(function(_pi_) {
expect(_pi_).toBe(3.14159);
}));
describe("Mocking pi and replace it with 42", function () {
beforeEach(angular.mock.module(function($provide) {
$provide.provider('pi', function() {
return {
'$get': function () { return 42; }
}
});
}));
it("Values are injected into controller", angular.mock.inject(function($controller, pi) {
var myController = createController($controller);
expect(myController.calculateCircumference(0.5)).toBe(42);
}));
});
function createController($controller, pi) {
return $controller("MyController", {
$scope: $scope
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment