describe("Agenda", function() {
});
it("Why we need that?", function(){});
it("Jasmine API", function(){});
it("Jasmine in AngularJS", function(){});
describe("How to testing", function(){
});
it("controller", function(){});
it("directive", function(){});
it("service", function(){});
I'm from Minsk
My name is Egor Miasnikov
});
describe("Who am I", function() {
I'm working at EPAM
And I'm the part of Nexgen team ;)
describe("Before we start", function() {
});
Do you care about quality of your applications?
describe("Before we start", function() {
});
Do you test your applications?
describe("Why we need that?", function() {
});
To ensure that what we create does what it’s supposed to do.
describe("Why we need that?", function() {
});
Something that works when one person is using it may not work when hundreds of people are using it.
describe("Why we need that?", function() {
});
There’s always a chance that a user really will do that – no matter how silly it seems.
describe("Why we need that?", function() {
});
There are lots of different devices, browsers, and operating systems out there.
describe("Why we need that?", function() {
});
We owe it to our users and ourselves to deliver the best application we can.
describe("Jasmine API", function() {
});
Statements & matchers & spies
describe("Jasmine API", function() {
});
describe( label, function(){ ... })
group tests together
describe("#Statements", function() {
});
describe("Jasmine API", function() {
});
it( label, function(){ ... })
label individual test
describe("#Statements", function() {
});
describe("Jasmine API", function() {
});
expect( actual )
used to compare against expected values
describe("#Statements", function() {
});
describe("Jasmine API", function() {
});
beforeEach(function(){ ... })
run prior to each it in the describe
describe("#Statements", function() {
});
describe("Jasmine API", function() {
});
afterEach(function() { ... })
run after each it in the describe
describe("#Statements", function() {
});
describe("Jasmine API", function() {
});
xdescribe( label, function(){ ... })
skip section ( note the x )
describe("#Statements", function() {
});
describe("Jasmine API", function() {
});
xit( label, function(){ ... })
skip test ( note the x )
describe("#Statements", function() {
});
describe("Jasmine API", function() {
});
to(Not)Be( null | true | false )
describe("#Matchers", function() {
});
to(Not)Match( regex | string )
to(Not)Equal( value )
toBeDefined()
toBeUndefined()
describe("Jasmine API", function() {
});
toBeNull()
describe("#Matchers", function() {
});
toBeFalsy()
toBeTruthy()
to(Not)Contain( string )
and more ...
describe("Jasmine API", function() {
});
spyOn( obj, method_string )
obj.stubbed.calls
obj.stubbed.mostRecentCall
obj.stubbed.calls[0].args
describe("#Spies", function() {
});
describe("Jasmine API", function() {
});
describe("#Spies", function() {
});
andCallThrough()
spy and delegate to real object
describe("Jasmine API", function() {
});
describe("#Spies", function() {
});
toHaveBeenCalledWith( array )
toHaveBeenCalled()
andReturn( value )
andCallFake(function() { ... })
describe( "Jasmine in AngularJS " , function () {
});
Karma & ngMocks
describe( "Jasmine in AngularJS " , function () {
});
Karma provides good setting environment to start your tests
describe( "Karma " , function () {
});
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'test/app-spec.js'
],
// list of files to exclude
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {},
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};
describe( "Jasmine in AngularJS " , function () {
});
describe( "ngMock " , function () {
});
// Set up the module
beforeEach(module('MyApp'));
//inject the $injector service
beforeEach(inject(function($injector) {
// Set up the mock http service responses
httpBackend = $injector.get('$httpBackend');
// getting RootScope
$rootScope = $injector.get('$rootScope');
// The $controller service is used to create instances of controllers
var $controller = $injector.get('$controller');
createController = function() {
return $controller('MyController', {'$scope' : $rootScope });
};
});
//inject the $httpBackend, $rootScope and $controller through inject method
beforeEach(inject(function($httpBackend, $rootScope, $controller) {
// Set up the mock http service responses
httpBackend = '$httpBackend';
createController = function() {
return $controller('MyController', {'$scope' : $rootScope });
};
});
describe( "How to testing " , function () {
});
Controllers & Directives & Services
describe( "How to testing " , function () {
});
inject or $injector
describe( "Controllers " , function () {
});
$controller
$RootScope
// Controller definition ...
myApp.controller('MyController', function($scope) {
window.console.log($scope.name);
});
// In a test ...
var scope;
beforeEach(inject(function($controller, $rootScope){
scope = $rootScope.$new();
scope.name = 'Egor';
$controller('MyController', {scope: scope});
scope.$apply()
}));
describe('myDirectiveController', function() {
it('should has name in its scope', {
expect(scope.name).toEqual('Egor');
});
});
describe( "How to testing " , function () {
});
inject or $injector
describe( "Directives " , function () {
});
$compile
$RootScope
//In code
app.directive('myDirective', function () {
return {
restrict: 'E',
replace: true,
template: '<h1>Sum of 1 and 1 is {{1 + 1}}</h1>'
};
});
In test
describe('Unit testing of my directive', function() {
var elem,
scope;
// Load the myApp module, which contains the directive
beforeEach(module('myApp'));
// Store references to rootScope and $compile
// so they are available to all tests in this describe block
beforeEach(inject(function($compile, $rootScope){
elem = angular.element("<my-directive></my-directive>");
scope = $rootScope.$new();
// Compile a piece of HTML containing the directive
elem = $compile(elem)(scope);
// fire all the watches, so the scope expression {{1 + 1}} will be evaluated
scope.$digest();
}));
it('Replaces the element with the appropriate content', function() {
// Check that the compiled element contains the templated content
expect(elem.html()).toContain("Sum of 1 and 1 is 2");
});
});
describe( "How to testing " , function () {
});
inject or $injector
describe( "Services " , function () {
});
$httpBackend
// In the code
angular.module('edm.interlock.dataAccess.endpoint.vehicle')
.service('VehicleMake', function ($resource, fulcrumConfig) {
var url = fulcrumConfig.urls.endpointUrl + '/api/v1/master/vehicle/makes/list';
var $resource(url, {state: 'new' }, {
'query': {
method: 'GET',
isArray: true,
transformResponse: function (data) {
var dataObj = angular.fromJson(data);
return dataObj.response.makes.sort(sortNames);
}
}
});
return {
query: function() {
return resource.query.apply(this, arguments);
}
}
});
//In the stub data
angular.module('nextgen-stub-data', ['ng'])
.value('stubMakes', [
{"id": 200002038, "name": "Acura", "niceName": "acura"},
{"id": 200001769, "name": "Aston Martin", "niceName": "aston-martin"},
{"id": 200000001, "name": "Audi", "niceName": "audi"},
{"id": 200000081, "name": "BMW", "niceName": "bmw"},
{"id": 200005848, "name": "Bentley", "niceName": "bentley"}
]);
//In the test
describe('VehicleMake resource', function(){
'use strict';
var $httpBackend, VehicleMake, makes;
beforeEach(function() {
module('nextgen-stub-data');
module('edm.interlock.dataAccess.endpoint.vehicle');
});
beforeEach(inject(function($injector) {
//inject all needed services
makes = $injector.get('stubMakes');
$httpBackend = $injector.get('$httpBackend');
VehicleMake = $injector.get('VehicleMake');
}));
it('should make HTTP GET request and return "makes"', function(){
//In this case we stub the real backend and when service make request
// this backend return our stub makes with code 200
$httpBackend.expectGET('/api/v1/vehicle/makes?fmt=json&state=new')
.respond(200, {'makes': makes});
var _makes = VehicleMake.query();
expect(_makes.length).toBe(5);
expect(_makes.length).toBe(makes.length);
});
});
describe( " How to testing " , function () {
});
inject or $injector
describe( "Controller with mock service " , function () {
});
$provide
$controller
...
//In the test
// Mock a resource base on stab data
beforeEach(module('edm.interlock.roadTest.articleContext', function($provide){
angular.injector(['nextgen-stub-data'])
//inject stub services
.invoke(function (StubArticleContext, stubArticleResponse) {
//create stub article context which replace the real one
$provide.value('articleContext', new StubArticleContext({
//create response for query method
query: stubArticleResponse.response[0]
}));
});
}));
beforeEach(inject(function($controller, $rootScope){
scope = $rootScope.$new();
ctrl = $controller('articlePartSixCtrl', {
$scope: scope
});
scope.$digest();
});
describe('twoSectionsBody controller', function() {
it('should receive data', function() {
//here we expect the length of sections based on stubArticleResponse
expect(scope.sections.length).toEqual(2);
});
});
describe( "Working time " , function () {
});
Get the code of workshop from github
describe( "Working time " , function () {
});
Go to github http://bit.ly/1J78IDT
describe( "Working time " , function () {
});
Download or clone project
describe( "Working time " , function () {
});
$ npm install -g karma-cli
describe( "Working time " , function () {
});
$ npm install
in working folder
describe( "Working time " , function () {
});
$ karma start
Jasmine
By Egor Miasnikov
Jasmine
Jasmine intro
- 902