Angular Unit Testing Helpers
Table of Contents
- Why?
- Features
- Installation
- TypeScript
- TestServ documentation
- TestServ examples
- TestElement documentation
- TestElement examples
- TestModule documentation
- TestModule examples
- TestFactory documentation
- TestFactory examples
- TestDummy documentation
- Dummy examples
Why?
I've created this package to simplify unit testing in AngularJS apps. I had enough of writing repeated code. For every spec (controller, directive, service) I had to write the same injector and compile blocks of code, for every mocked service I had to write the same lines. With this package, everything becomes easier and faster.
Features
All selectors are using native Javascript querySelector
or querySelectorAll
, so jQuery
is not requierd.
Installation:
- Download package:
npm install angular-unit-testing-helpers
or
bower install angular-unit-testing-helpers
- Inject it to
karma.conf.js
files: 'node_modules/angular-unit-testing-helpers/test-helpers.js' ...
or
files: 'bower_components/angular-unit-testing-helpers/test-helpers.js' ...
- Or import directly from package
;
const TestServ = TestServ;const TestElement = TestElement;
TypeScript:
You can use this library with TypeScript. All you need to do:
- Have typings installed (1.x):
npm install typings
- Have installed angular, angular-mocks and jquery typings
typings install dt~jquery --save --global
typings install dt~angular --save --global
typings install dt~angular-mocks --save --global
- Have installed typings in angular-unit-testing-helpers
typings install npm:angular-unit-testing-helpers
TestServ documentation
TestServ contructor:
Without an argument:
It will create an empty object;
With an argument:
'$q';
It will return real $q
service;
Implementation:
window { var _this = this; if !!name ; return _this; };
addMethod:
var someService = ;someService;
addMethod
will add an empty function to the someService at name
value and also create spyOn on this created method. spyOn will return returnedValue
.
returnedValue
can be undefined, a value, an object or a function.
You can also construct chaining methods calls, for example:
var someService = ;someService;
More in examples.
Implementation:
{ if typeof returnedValue === "function" thisname = returnedValue; and; else thisname = angularnoop; and; return this;}
addPromise:
var someService = ;someService;
addPromise
will add an empty function to the someService at name
value and also create spyOn on this created method. Same as addMethod
.
But spyOn will return object with then
property, which will become a function. aThis function will bind two arguments to success
and error
property of someService[name]
. So to call success promise you will simply call someService[name].success()
and for failure promise someService[name].fail
. You can also call this function with arguments (someService[name].success('someString')
), so when you call this someService[name].then(function(response) { console.log(response)}), response will become
'someString'`.
You can also construct chaining methods calls, for example:
var someService = ;someService;
Implementation:
{ var _this = this; _thisname = {}; and; return this;}
addProperty:
var someService = ;someService;
addProperty
will add a property to the someService with returnedValue as a value.
You can also construct chaining methods calls, for example:
var someService = ;someService;
More in examples.
Implementation:
{ thisname = returnedValue; return this;}
get:
var someService = ;someService;
get
will return property from a created service. You can use direct propery call (someService.name), this method is useful with typescript. More in typescript chapter.
someService === someServicename;
Implementation:
{ return thisname;}
TestServ examples
TestElement documentation
TestElement contructor:
;
It will create an object, which will contain some angular services: $rootScope
, $compile
, $timeout
, $controller
, $templateCache
;
Implementation:
window { var _this = this; ; thisname = '';};
createCtrl:
var element someController services = someSrevice: mockedSomeService;element = ;someController = element;
createCtrl
will create and return a controller with 'name' and services object. You don't need to inject $scope
into services
method, it's injected by default if services.$scope doesn't exists.
Implementation:
{ if !services services = {}; if !services$scope services$scope = this_$scope; this_ctrl = this; return this_ctrl;}
addTemplate:
var element;element = ;element;element;
addTemplate
will create and return an angular element with current $scope. path
is a path to the template that is stored in $templateCache. ctrlAs is an optional argument. If you are using controllerAs
syntax, then ctrlAs
should be the value of controllerAs
property.
Implementation:
{ var template; template = this$templateCache; this_el = angular; if !!ctrlAs this_$scopectrlAs = this_ctrl; thisthis_$scope; this_$scope; try this$timeout; catch e this$timeout; return this_el;}
createDirective:
var element;element = ;element;
createDirective
will create and return an angular element with with html
and scope
. name
is a name of the directive, html
is a string and scope
is an object, e. g.: name = 'someDirective', html = '<some-directive attribute="someValue"></some-directive>'; scope = { someValue: 123 };
.
Implementation:
{ thisname = name; this_$scope = angular; this_el = thisthis_$scope; this_$scope; try this$timeout; catch e this$timeout; return this_el;}
createComponent:
var element;element = ;element;
createComponent
is an alias to createDirective method.
Implementation:
{ this; return this_el;}
createFilter:
var filter;filter = ;
createFilter
will return filter with given name.
Implementation:
{ return this;}
get scope:
elementscope
scope
will return current scope of the element.
Implementation:
{ return this_ctrl ? this_$scope : Objectlength ? thisdomscope : thisdomscope;}
get ctrl:
elementctrl
ctrl
will return controller created with createCtrl
method or controller created with createDirective
method.
Implementation:
{ return this_ctrl ? this_ctrl : angular;}
get dom:
elementdom
dom
will return current angular element of the template created with addTemplate
or the directive created with createDirective
.
Implementation:
{ return angular;}
find:
element
find
will return found angular element with selector
.
Implementation:
{ return angular;}
findAll:
element
findAll
will return all found angular elements with selector
as an array.
Implementation:
{ var htmlObject = thisdom0; var returnedArray = ; for var property in htmlObject if htmlObject && typeof htmlObjectproperty !== 'number' returnedArray; return returnedArray;}
destroy:
element
destroy
will destroy current element.
Implementation:
{ this_$scope; this_el = null; this_ctrl = null;}
clickOn:
element;
clickOn
will click on element found with selector
and make a $scope.$digest()
. It returns a promise.
Implementation:
{ if thisdom0 thisdom0; else thisdom0; this_$scope; return this;}
inputOn:
element;
inputOn
will set value of the element found with selector
, trigger a input
handler and make $scope.$digest()
. It returns a promise.
If you have many inputs with the same selector, then you can pass which input you want to react with by adding number as a third argument (0 is a first input). which
is an optional argument.
Implementation:
{ if !which if thisdom0 angular; else if thisdom0tagName == 'INPUT' this_el; else if thisdom0which angular; else if thisdom0tagName == 'INPUT' this_el; this_$scope; return this;}
TestElement examples
TestModule documentation
TestModule contructor:
name;
It will create an module object with given name
;
Implementation:
window { thismodule = angular; thisdeps = thismodulevaluenamerequires;};
hasModule:
var someModule = moduleName;someModule;
hasModule
will return boolean
value: true
if moduleName
has dependencyModule as a dependency and false
if not.
Implementation:
{ return thisdeps >= 0;}
TestModule examples
TestFactory documentation
define:
TestFactory;
define
will define a model with attributes
for creating factories (it can be also a sequence
). name
should be unique. It should be called before any create action. The best solution is to define models in seperate folder and inject it at the beginning of the karma.config
file (but after test-helpers
).
Example:
TestFactory;
create:
TestFactory
create
will create an object with model named name
. attributes
are an optional argument, it overwrites default attributes defined with define
method.
Example:
user = TestFactory
createList:
TestFactory
createList
will create an collection of object with model named name
. number
defines how many objects in collections should be added. attributes
are an optional argument, it overwrites default attributes defined with define
method.
Example:
users = TestFactory
defineSequence:
TestFactory
defineSequence
will define a model with attributes
for creating factories. name
should be unique. It should be called before any sequence call. argOne
can be iterator or function.
Example:
TestFactory; // => 1,2,3...TestFactory; // => 4,8,12...TestFactory; // => 'Name 1', 'Name 2', 'Name 3'...TestFactory; // => 'Age 5', 'Age 10', 'Age 15'...
sequence:
TestFactory;TestFactory;
sequence
returns a function. When you call it, then sequnce will increment. When you call clear
method on it, then sequnce will be cleared to default value;
Example:
TestFactory;TestFactory; // => 1TestFactory; // => 2TestFactoryclear;TestFactory; // => 1TestFactory; // => 2
TestFactory examples
TestDummy documentation
filter:
TestDummyfilter;
filter
will return the simpliest filter. It's useful when filter is in another module.
Implementation:
{ return { return input; };}
directive:
TestDummydirective
directive
will return the simpliest directive. It's useful when directive is in another module.
Implementation:
{ return restrict: 'AE' ;}