[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 ...
随机推荐
- python 多线程编程
这篇文章写的很棒http://blog.csdn.net/bravezhe/article/details/8585437 使用threading模块实现多线程编程一[综述] Python这门解释性语 ...
- yum自动脚本
echo -e "\033[34mstop server:\033[0m" service iptables stop service NetworkManager stop ch ...
- 一个通用的makefile
# ESDK the makefile setting file - chenwg@20131014 # you can modify "PC = 1" such as " ...
- By Yupei Zhang
Sparse Learning: Sparsity Learning (foundation) (1) Emergence of simple-cell receptive field propert ...
- 在ios中使用第三方类库
在项目开发中经常会用到一些第三方类库,通常有两种方法来做到:一种方法是直接把所有的.h和.m文件复制到项目中:另一种方法是把.xcodeproj拖到项目中生成静态链接库并引用. 方法一:直接复制所有源 ...
- 编写高质量代码改善C#程序的157个建议读书笔记【1-10】
开篇 学生时代,老师常说,好记性不如烂笔头,事实上确实如此,有些知识你在学习的时候确实滚瓜烂熟,但是时间一长又不常用了,可能就生疏了,甚至下次有机会使用到的时候,还需要上网查找资料,所以,还不如常常摘 ...
- 安卓-PC-Arduino3方通信实现
请仔细理解相关参数,如端口设置.IP设置.COM口设置......等等.....不要盲目COPY.....这涉及手机.电脑和一个单片机,其中一台电脑作为服务器并与单片机相连,负责通过网络与客户端通信( ...
- ajaxSubmit与ajaxFileUpload的空值
ajaxSubmit发现正文无内容, ajaxFileUpload发现无上传内容, 嗯,你只是忘记了 html 中控件的 name 没有指定,这哥们不认 id 的.
- LRU缓存实现(Java)
LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的 ...
- 成功安装mysql后,为何服务管理器里找不到MYSQL服务名
1.打开cmd,切换到mysql的bin目录下 2. D:\Program Files\MySQL5.1\bin>mysqld.exe -installService successfully ...