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