【发布时间】:2014-01-08 18:55:27
【问题描述】:
我有以下指令:
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' : '';
}
}
}
}
我想模拟依赖项以使用单元测试已知的值对不同的代码路径进行单元测试。我有以下示例单元测试:
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');
}
));
这给了我两个问题。
首先,由于模板位于外部文件中,因此在加载时会尝试获取它并出错,因为找不到该文件,这是合乎逻辑的,因为它处于测试环境而不是实际服务器中。
其次,没有明显的方法可以模拟通过构造函数注入指令的依赖项。在测试控制器时,您可以使用 $controller 服务,但由于指令是通过编译具有传递范围的 html 标记间接实例化的,因此无法直接实例化它(例如,没有类似的 $directive)。这阻碍了我将$userDetails.name 和$userDetails.gravatar 分别设置为'test name' 和'test avatar'。
如何让指令正确编译并使用自定义 $userDetails 依赖项运行?
【问题讨论】:
标签: unit-testing angularjs dependency-injection angularjs-directive karma-runner