Skip to content

Instantly share code, notes, and snippets.

@MikeyBurkman
Last active June 29, 2017 20:30
Show Gist options
  • Save MikeyBurkman/870892e1bcf272a6f0458d4defccc7ae to your computer and use it in GitHub Desktop.
Save MikeyBurkman/870892e1bcf272a6f0458d4defccc7ae to your computer and use it in GitHub Desktop.
Angular Directive Testing
'use strict';
describe('my-foo-directive', function() {
var testDirective;
var directive;
beforeEach(module('app.test.directive'));
beforeEach(module('app.templates'));
beforeEach(module('app.components.myFooDirective'));
beforeEach(
inject(function(_testDirective_) {
testDirective = _testDirective_;
})
);
describe('#foo', function() {
it('Should work', function() {
directive = testDirective.getIsolate({
html: '<my-foo query="query"></my-foo>',
parentScope: {
query: 'abc'
}
});
expect(directive.html).to.contain('<div>query: abc</div>');
expect(directive.vm.getQuery()).to.eql('abc');
});
});
});
'use strict';
/**
* This is used for instantiating directives for testing
*/
angular.module('app.test.directive', []).factory('testDirective', function() {
/**
* Instantiates a directive that has has an isolate scope
*/
function getIsolate(opts) {
var $rootScope;
var $compile;
inject(function(_$rootScope_, _$compile_) {
$rootScope = _$rootScope_;
$compile = _$compile_;
});
var html = opts.html; // Required -- same as what would be in an html template
var parentScope = opts.parentScope; // Optional
var ctrlName = opts.ctrlName || 'ctrl';
var scope = $rootScope.$new();
Object.keys(parentScope || {}).forEach(function(name) {
scope[name] = parentScope[name];
});
var el = $compile(html)(scope);
try {
scope.$digest();
} catch (err) {
if (err.message.indexOf('Unexpected request: GET') > -1) {
throw new Error(
'It appears you forgot to import the \'app.templates\' module: \n' +
err.message +
'\n' +
err.stack
);
} else {
throw err;
}
}
var resultHtml = el.html();
if (!resultHtml) {
throw new Error(
'The directive you are testing did not generate any html. ' +
'Are you sure you spelled the element name correctly and ' +
'imported the directive module?'
);
}
var isolateScope = el.isolateScope();
if (!isolateScope) {
throw new Error('It looks like this directive has no isolate scope');
}
var vm = isolateScope[ctrlName];
if (!vm) {
throw new Error(
'No controller found in the directive with name "' +
ctrlName +
'". Make sure that either you controller is named correctly, or you set the \'ctrlName\' ' +
'option when calling getIsolate()'
);
}
return {
vm: vm,
html: resultHtml,
parentScope: scope
};
}
return {
getIsolate: getIsolate
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment