I have the following directive:
function TopLevelMenuDirective ($userDetails, $configuration) {
return {
restrict:'A',
templateUrl: staticFilesUri + 'templates/TopLevelMenu.Template.html',
scope: {
activeTab: '='
},
link: function (scope, element, attributes) {
var userDetails = $userDetails;
if ($userDetails) {
scope.user = {
name: userDetails.name ? userDetails.name : 'KoBoForm User',
avatar: userDetails.gravatar ? userDetails.gravatar: (staticFilesUri + '/img/avatars/example-photo.jpg')
};
} else {
scope.user = {
name: 'KoBoForm User',
avatar: staticFilesUri + '/img/avatars/example-photo.jpg'
}
}
scope.sections = $configuration.sections();
scope.isActive = function (name) {
return name === scope.activeTab ? 'is-active' : '';
}
}
}
}
I want to mock the dependencies to unit test the different code paths with values known by the unit tests. I have the following sample unit test:
it('should set $scope.user to values passed by $userDetails',
inject(function($compile) {
var element = '<div top-level-menu></div>';
element = $compile(element)($scope);
$scope.$apply();
expect(element.isolateScope().user.name).toBe('test name');
expect(element.isolateScope().user.avatar).toBe('test avatar');
}
));
This gives me two problems.
First, since the template is in an external file, when it loads it tries to fetch it and errors out beacause the file is nowhere to be found, which is logical since it's in a test environment and not an actual server.
Second, there's no apparent way to mock the dependencies injected into the directive through its constructor. When testing controllers you can use the $controller service, but since directives are instantiated indirectly by compiling an html tag with a passed scope, there's no way to instantiate it directly (e.g. there's no analogous $directive). This impedes me from setting $userDetails.name and $userDetails.gravatar to 'test name' and 'test avatar' respectively.
How do I get the directive to compile properly and run with a custom $userDetails dependency?