Test Angular Directive With Isolate Scope
Directives with isolate scope do not inherit their scope from their parent. Thus, the pattern to test them is slightly different.
When testing a directive, you’ll often want to setup some fixture element to attach your directive to. This will act as the DOM that you will compile with scope. At that point, the variables that you attached to scope will be available within the directive under test.
For example, if I had a directive called
AccountList with isolate scope:
angular.module('app').directive 'AccountList', -> restrict: 'EA' replace: true scope: accounts: '=' # etc ...
Then I would setup my test something like this:
describe 'AccountList', -> elm = null beforeEach inject ($rootScope, $compile) -> accounts =  for num in [1..5] accounts.push createFakeAccount() $rootScope.accounts = accounts elm = angular.element """ <account-list accounts="accounts"></account-list> """ e = $compile(elm)($rootScope) e.scope().$digest() # actual specs, using elm ...
A few points:
angular-mock. It is currently only supported in Jasmine.
- Before each test of the
AccountListdirective, a set of 5 accounts will be put in scope so the directive, presumably, has something to display.
$rootScopeis going to be the only scope that you can get to easily from your tests. You can attach variables to it directly as above or call
$rootScope.$new()to generate a new scope if you’d like.
- We initially
$compilethe fixture element, passing in
- To get Angular to actually act internally on the variables that we’ve passed into the directive and put them on scope, we must call the important line of code:
Now you should be ready to rock and roll with your tests. Isolate scopes can be tricky. Testing them, a bit tricky as well.
Do you know a better way?