AngularJS example MotoAds unit tests
| Unit tests result: | Application folders tree: |
|
|
controllers.js):
motoAdsApp.controller('AdvertsController', ['$scope', 'Brand', 'Country', 'Advert',
function($scope, Brand, Country, Advert) {
$scope.oneAtATime = true;
$scope.brands = Brand.query();
$scope.countries = Country.query();
$scope.sortByCols = [{
"key": "year",
"name": "Year"
}, {
"key": "price",
"name": "Price"
}];
$scope.adverts = [];
var allAdverts = Advert.query(filterAdverts);
$scope.filter = {
brandName: null,
modelName: null,
country: null,
region: null,
yearFrom: null,
yearTo: null
};
$scope.isAnyFilter = function() {
var f = $scope.filter;
if (f.brandName || f.modelName || f.country || f.region || f.yearFrom || f.yearTo) {
return true;
}
return false;
};
$scope.removeAllFilter = function() {
$scope.filter = {
brandName: null,
modelName: null,
country: null,
region: null,
yearFrom: null,
yearTo: null
};
};
$scope.addBrandModelFilter = function(brand, model) {
$scope.filter.brandName = brand.name;
$scope.filter.modelName = model.name;
};
$scope.$watch('filter', filterAdverts, true);
function filterAdverts() {
$scope.adverts = [];
angular.forEach(allAdverts, function(row) {
if (!$scope.filter.country) {
$scope.filter.region = null;
}
if ($scope.filter.brandName && $scope.filter.brandName !== row.brandName) {
return;
}
if ($scope.filter.modelName && $scope.filter.modelName !== row.modelName) {
return;
}
if ($scope.filter.country && $scope.filter.country.name !== row.countryName) {
return;
}
if ($scope.filter.region && $scope.filter.region.name !== row.regionName) {
return;
}
if ($scope.filter.yearFrom && $scope.filter.yearFrom > row.year) {
return;
}
if ($scope.filter.yearTo && $scope.filter.yearTo < row.year) {
return;
}
$scope.adverts.push(row);
});
};
}]);
]]>
We should write the script for running unit tests (test.bat):
@echo off REM Windows script for running unit tests REM You have to run server and capture some browser first REM REM Requirements: REM - NodeJS (http://nodejs.org/) REM - Karma (npm install -g karma) set BASE_DIR=%~dp0 karma start "%BASE_DIR%\..\config\karma.conf.js" %* ]]>We configure Karma for our tests (karma.conf.js):
module.exports = function(config){
config.set({
basePath : '../',
files : [
'app/lib/angular/angular.js',
'app/lib/angular/angular-*.js',
'app/lib/ui-bootstrap/ui-bootstrap-*.js',
'app/lib/angular/angular-mocks.js',
'app/js/**/*.js',
'test/unit/**/*.js'
],
exclude: ['app/lib/angular/angular-scenario.js'],
autoWatch : true,
frameworks: ['jasmine'],
browsers : ['Chrome'],
plugins : [
'karma-junit-reporter',
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-jasmine'
],
junitReporter : {
outputFile: 'test_out/unit.xml',
suite: 'unit'
}
});};
]]>
When everything is ready we can start writing tests in controllersSpec.js.
Step 1
We prepare dummy data:
var BRANDS_RESPONSE = [
{"name": "Audi", "models": [{"name": "A1"}, {"name": "A3"}]},
{"name": "Dacia", "models": [{"name": "Duster"}, {"name": "Logan"}]}
];
var COUNTRIES_RESPONSE = [
{"name": "Germany", "regions": [{"name": "Bavaria"}, {"name": "Hesse"}]},
{"name": "Poland", "regions": [{"name": "Lesser Poland"}, {"name": "Masovia"}]}
];
var ADVERTS_RESPONSE = [
{
"brandName": "Audi",
"modelName": "A1",
"year": 2011,
"price": "35000",
"imageUrl": "img/audi_a1_1.jpg",
"countryName": "Germany",
"regionName": "Bavaria"
},
{
"brandName": "Audi",
"modelName": "A1",
"year": 2010,
"price": "30000",
"imageUrl": "img/audi_a1_2.jpg",
"countryName": "Poland",
"regionName": "Masovia"
},
{
"brandName": "Dacia",
"modelName": "Duster",
"year": 2012,
"price": "33000",
"imageUrl": "img/dacia_duster_1.jpg",
"countryName": "Poland",
"regionName": "Masovia"
},
{
"brandName": "Dacia",
"modelName": "Duster",
"year": 2009,
"price": "27000",
"imageUrl": "img/dacia_duster_2.jpg",
"countryName": "Germany",
"regionName": "Bavaria"
}];
]]>
Step 2
Load modules, define dummy services, initialize scope, controller and filter:
describe('MotoAds controllers', function() {
beforeEach(module('motoAdsApp'));
beforeEach(module('ui.bootstrap'));
beforeEach(module('motoAdsServices'));
describe('AdvertsController', function() {
var scope, ctrl, $httpBackend, orderByFilter;
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller, $filter) {
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('data/brands.json').respond(BRANDS_RESPONSE);
$httpBackend.expectGET('data/countries.json').respond(COUNTRIES_RESPONSE);
$httpBackend.expectGET('data/adverts.json').respond(ADVERTS_RESPONSE);
orderByFilter = $filter('orderBy');
scope = $rootScope.$new();
ctrl = $controller('AdvertsController', {$scope: scope});
}));
// TEST WILL BE HERE
});
});
]]>
Step 3
We write first test - filtering by brand and model:
it('should filter by brand and model', function() {
expect(scope.adverts).toEqual([]);
$httpBackend.flush();
expect(scope.adverts.length).toBe(4);
scope.$apply(function() {
scope.filter = {
brandName: "Audi",
modelName: "A1",
country: null,
region: null,
yearFrom: null,
yearTo: null
};
});
expect(scope.adverts.length).toBe(2);
});
]]>
Step 4
We write second test - filtering by country and region:
it('should filter by country and region', function() {
expect(scope.adverts).toEqual([]);
$httpBackend.flush();
expect(scope.adverts.length).toBe(4);
scope.$apply(function() {
scope.filter = {
brandName: null,
modelName: null,
country: {name: "Germany"},
region: {name: "Bavaria"},
yearFrom: null,
yearTo: null
};
});
expect(scope.adverts.length).toBe(2);
});
]]>
Step 5
We write third test - filtering by year:
it('should filter by from yearFrom to yearTo', function() {
expect(scope.adverts).toEqual([]);
$httpBackend.flush();
expect(scope.adverts.length).toBe(4);
scope.$apply(function() {
scope.filter = {
brandName: null,
modelName: null,
country: null,
region: null,
yearFrom: 2011,
yearTo: 2012
};
});
expect(scope.adverts.length).toBe(2);
});
]]>
Step 6
We write fourth test - sorting by year:
it('should sort by year', function() {
expect(scope.adverts).toEqual([]);
$httpBackend.flush();
expect(scope.adverts.length).toBe(4);
var sortedAdverts = orderByFilter(scope.adverts, "year");
var prevYear = 0;
for (var i = 0; i < sortedAdverts.length; i++) {
var advert = sortedAdverts[i];
expect(advert.year).toBeGreaterThan(prevYear);
prevYear = advert.year;
}
});
Step 7
We run unit test in Node.js command prompt by running
test.bat and we should see:
D:\devhome\github\motoads>scripts\test.bat INFO [karma]: Karma v0.10.4 server started at http://localhost:9876/ INFO [launcher]: Starting browser Chrome INFO [Chrome 30.0.1599 (Windows Vista)]: Connected on socket QZD2lLpZ-KlcZE2pqcrE Chrome 30.0.1599 (Windows Vista): Executed 4 of 4 SUCCESS (0.517 secs / 0.076 secs) ]]>
If you want to run this example on your computer, you can download sources from GitHub.
Any comment would be highly appreciated.


Komentarze