[Unit Testing] AngularJS Unit Testing - Karma
Install Karam:
npm install -g karma
npm install -g karma-cli
Init Karam:
karma init
First test:
1. Add test file to the karma.conf.js:
// list of files / patterns to load in the browser
files: [
'test/hello.js'
],
2. Add test file:
describe('First Unit testing with Karma', function() {
it('sholud work', function() {
expect(true).toBe(false);
})
})
Of course, it will failed.
Then we make it pass:
describe('First Unit testing with Karma', function() {
it('sholud work', function() {
expect(true).toBe(true);
})
})
Testing with AngularJS
Install angular-mocks:
npm install angular-mocks
Include the angular.js and angular-mocks.js file before the test file:
// list of files / patterns to load in the browser
files: [
'test/hello.js',
'bower_components/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'test/anuglarjs.js'
],
Write the test file:
describe('Testing with AngularJS', function() {
//Want $scope and element can be used globally
var $scope,
element;
//We need to inject $compile, $rootScope
beforeEach(inject(function($compile, $rootScope) {
$scope = $rootScope;
//create an 'angular element'
element = angular.element("<div>{{2+2}}</div>");
//then compile it to real angular element
//also it requires link function and scope
element = $compile(element)($rootScope);
}));
it('should equals to 4', function() {
//make sure to $digest() it to get the change
$scope.$digest();
expect(element.html()).toBe("5"); // change to "4" to make it pass
})
})
Now, "4" is not "5", then it will failed, switch to "4" to make it pass.
Testing Directive:
.directive('aGreatEye', function () {
return {
restrict: 'E',
replace: true, //Important to add replace: true, otherwise, it would be <h1 class="ng-binding">...</h1>"
template: '<h1>lidless, wreathed in flame, {{1 + 1}} times</h1>'
};
});
describe('Testing directive', function() {
var $scope,
$compile,
element;
beforeEach(module('app'));
beforeEach(inject(function(_$compile_, _$rootScope_) {
$compile = _$compile_;
$scope = _$rootScope_;
}));
it("Replaces the element with the appropriate content", function() {
element = $compile('<a-great-eye></a-great-eye>')($scope);
$scope.$digest();
expect(element.html()).toBe('lidless, wreathed in flame, 2 times');
})
});
Underscore notation: The use of the underscore notation (e.g.: _$rootScope_) is a convention wide spread in AngularJS community to keep the variable names clean in your tests. That's why the $injector strips out the leading and the trailing underscores when matching the parameters. The underscore rule applies only if the name starts and ends with exactly one underscore, otherwise no replacing happens.
Testing Directives With External Templates:
1. Install 'karma-ng-html2js-preprocessor': https://github.com/karma-runner/karma-ng-html2js-preprocessor
npm install karma-ng-html2js-preprocessor --save-dev
2. Add config to karma.config.js:
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'*.html': ['ng-html2js']
}, ngHtml2JsPreprocessor: {
// strip this from the file path
stripPrefix: '/' //because currently all the html files are located in / root
},
3. Add html into beforeEach:
describe('Testing directive', function() {
var $scope,
$compile,
element;
beforeEach(module('app'));
// Add html file here
beforeEach(module('directivetest.html'));
beforeEach(inject(function(_$compile_, _$rootScope_) {
$compile = _$compile_;
$scope = _$rootScope_;
}));
it("Replaces the element with the appropriate content", function() {
element = $compile('<a-great-eye></a-great-eye>')($scope);
$scope.$digest();
expect(element.html()).toBe('lidless, wreathed in flame, 2 times');
})
});
.directive('aGreatEye', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'directivetest.html'
};
});
/*directivetest.html*/
<h1>lidless, wreathed in flame, {{1 + 1}} times</h1>
Testing Directive Scope:
1. Check after a click event, scope value changed:
.directive('aGreatEye', function () {
return {
restrict: 'EA',
replace: true,
templateUrl: 'directivetest.html',
link: function(scope, element) {
scope.isClicked = false;
element.bind('click', function() {
scope.isClicked = true;
})
}
};
});
it("isClicked is true after click", function() {
element = $compile('<a-great-eye></a-great-eye>')($scope);
$scope.$digest();
element.triggerHandler('click');
expect($scope.isClicked).toBe(true);
});
2. Isolated scope testing:
.directive('aGreatEye', function () {
return {
restrict: 'EA',
replace: true,
scope: {},
templateUrl: 'directivetest.html',
link: function(scope, element) {
scope.isClicked = false;
element.bind('click', function() {
scope.isClicked = true;
})
}
};
});
it("isolated scope testing", function() {
element.triggerHandler('click');
expect(element.isolateScope().isClicked).toBe(true);
});
You can no long use "element.scope()" or "$scope", you should use "element.isolateScope()".
Testing Directive Scope Binding:
Tow ways binding:
.directive('aGreatEye', function () {
return {
restrict: 'EA',
replace: true,
scope: {
flavor: "=" //Accpet an object
},
templateUrl: 'directivetest.html',
link: function(scope, element) {
element.bind('click', function() {
scope.isClicked = true;
scope.flavor.message += " World!";
})
}
};
});
beforeEach(inject(function(_$compile_, _$rootScope_) {
$compile = _$compile_;
$scope = _$rootScope_;
$scope.goPro = {message: "Hello"};
element = $compile('<div a-great-eye flavor="goPro"></div>')($scope);
$scope.$digest();
}));
it("after click the scope.data should be Hello World!", function() {
element.triggerHandler('click');
expect($scope.goPro.message).toBe('Hello World!');
expect(element.isolateScope().flavor.message).toBe("Hello World!");
});
Testing Speed:
Using ddescriber plugin to speed up unit testing.
Install the plugin "ddscriber for jasmine". Ctrl+Shift+D, to open the dailog. In the dialog you can choose which test to be included or not.

The code is modfied as:
/**
* Created by Answer1215 on 1/16/2015.
*/
ddescribe('Testing directive', function() {
var $scope,
$compile,
element; beforeEach(module('app')); beforeEach(module('directivetest.html')); beforeEach(inject(function(_$compile_, _$rootScope_) {
$compile = _$compile_;
$scope = _$rootScope_;
$scope.goPro = {message: "Hello"};
element = $compile('<div a-great-eye flavor="goPro"></div>')($scope);
$scope.$digest();
})); iit("Replaces the element with the appropriate content", function() {
expect(element.html()).toContain("lidless, wreathed in flame, 2 times");
}); //it("isClicked is true after click", function() {
// element.triggerHandler('click');
// expect($scope.isClicked).toBe(true);
//}); iit("isolated scope testing", function() {
element.triggerHandler('click');
//expect(element.isolateScope().isClicked).toBe(true);
}); xit("after click the scope.data should be Hello World!", function() {
element.triggerHandler('click');
expect($scope.goPro.message).toBe('Hello World!');
//expect(element.isolateScope().flavor.message).toBe("Hello World!");
});
}); xdescribe("error driective testing", function() { var $scope, $compile, element; beforeEach(module('app')); beforeEach(module('error.html')); beforeEach(inject(function(_$compile_, _$rootScope_) {
$scope = _$rootScope_;
$compile = _$compile_; element = $compile('<error></error>')($scope);
$scope.$digest();
})); iit("Should contains alert-danger class", function() {
expect(element.find('div').hasClass('alert-danger')).toBe(true);
});
});
ddscribe / iit -- include
xdscribe / xit -- exclude
Testing Service:
Testing service, you need to inject the service into beforeEach.
ddescribe('testing service', function() {
var SmithService;
beforeEach(module('app'));
beforeEach(inject(function(_SmithService_) {
SmithService = _SmithService_;
}));
iit('should append Smith after each name', function() {
expect(SmithService.getName("John")).toBe("John Smith");
})
});
This testing case is test whenever use a service to get a name we will append " Smith" to the end.
.service('SmithService', function() {
var SmithService = {};
SmithService.getName = function(name) {
return name + " Smith";
}
return SmithService;
});
Testing Controller:
Testing controller, you need to inject the $controller into beforeEach. And get ctrl instence by using:
appCtrl = $controller("AppCtrl")
ddescribe('Test Controller', function() {
var ctrl;
beforeEach(module('app'));
beforeEach(inject(function(_$controller_) {
ctrl = _$controller_("TestCtrl");
}));
iit('Test Controller', function() {
expect(ctrl.message).toBe("Hello");
});
});
.controller('TestCtrl', function() {
var vm = this;
vm.message = "Hello";
});
[Unit Testing] AngularJS Unit Testing - Karma的更多相关文章
- Unit Testing, Integration Testing and Functional Testing
转载自:https://codeutopia.net/blog/2015/04/11/what-are-unit-testing-integration-testing-and-functional- ...
- Difference Between Performance Testing, Load Testing and Stress Testing
http://www.softwaretestinghelp.com/what-is-performance-testing-load-testing-stress-testing/ Differen ...
- AngularJS测试框架 karma备忘
AngularJS测试框架karma安装 安装karma $ --save-dev 安装karma组件 $ npm install karma-jasmine karma-chrome-launche ...
- Go testing 库 testing.T 和 testing.B 简介
testing.T 判定失败接口 Fail 失败继续 FailNow 失败终止 打印信息接口 Log 数据流 (cout 类似) Logf format (printf 类似) SkipNow 跳过当 ...
- [Angular + Unit] AngularJS Unit testing using Karma
http://social.technet.microsoft.com/wiki/contents/articles/32300.angularjs-unit-testing-using-karma- ...
- [AngularJS Unit tesint] Testing keyboard event
HTML: <div ng-focus="vm.onFocus(month)", aria-focus="{{vm.focus == month}}", ...
- [AngularJS + Unit Testing] Testing Directive's controller with bindToController, controllerAs and isolate scope
<div> <h2>{{vm.userInfo.number}} - {{vm.userInfo.name}}</h2> </div> 'use str ...
- [AngularJS + Unit Testing] Testing a component with requiring ngModel
The component test: describe('The component test', () => { let component, $componentController, $ ...
- [Unit Testing] Fundamentals of Testing in Javascript
In this lesson, we’ll get the most fundamental understanding of what an automated test is in JavaScr ...
随机推荐
- jQuery遮罩层效果
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- Lintcode 175 Invert Binary Tree
I did it in a recursive way. There is another iterative way to do it. I will come back at it later. ...
- codeforces 427E
题意:给定一位空间里n个点的坐标,每个坐标有一个罪犯,现在要建一个警局,并且这个警局只有一辆车,车一次最多载m个人,问应建在哪是的抓回所有罪犯的路程和最小. 思路: 很明显建在罪犯的点上一定可以找到最 ...
- SQLSERVER复制的要点
SQLSERVER复制的要点 在论坛里经常有人问:SQLSERVER复制出问题了!!SQLSERVER复制不运行了!!SQLSERVER复制遇到阻塞了!! 然后最后来一句:“怎麽办?????????? ...
- elixir 高可用系列(一) Agent
概述 elixir 本身是一种 immutable 的语言,默认情况下,进程间是不共享任何状态的,进程之间通过消息来交互. 而 Agent 则封装了一种进程间共享状态的方式,通过这种方式,不用显式的写 ...
- 51单片机-PC数据传输 温度 距离 监控系统设计
>_<:功能概述: 通过串口PC和单片机通信,可以询问单片机测得的温度,可以询问声呐测距的测量距离,同时把测量温度显示在数码管上. >_<:PC部分 这里com.cpp和com ...
- Deployment Pipeline using Docker, Jenkins, Java
Deployment Pipeline using Docker, Jenkins, Java and Couchbase http://blog.couchbase.com/2016/septemb ...
- 说不尽的MVVM(2) – MVVM初体验
知识预备 阅读本文,我假定你已经具备以下知识: C#.WPF基础知识 了解Lambda表达式和TPL 对事件驱动模型的了解 知道ICommand接口 发生了什么 某程序员接到一个需求,编写一个媒体渲染 ...
- 移动开发下Xamarin VS PhoneGap
跨平台开发 移动应用开发对很多开发人员来说是一种令人恐惧的事情.许多企业希望能够通过开发移动应用程序,来提升企业业务水平,开发原生App时往往又缺少专业的Objective C 或 Java 移动开发 ...
- 相对路径获取项目文件 及报错 No mapping found for HTTP request with URI XXX in DispatcherServlet with name ‘springmvc’解决方法
首先一点,WebRoot目录下的文件是都可以通过浏览器输入路径,直接读取到的 例如这样: 而WebRoot下面WEB-INF是无法浏览器输入路径直接读取的. 因为是受保护的. 如果jsp读取一个图片的 ...