我试图用Karma和Jasmine来测试一个使用几个东西的指令。首先是它使用一个templateUrl,其次是它定义一个控制器。这可能不是正确的术语,但它的声明中会创建一个控制器。 Angular应用程序被设置为使得每个单元都包含在其自己的模块中。例如,所有指令都包含在模块app.directive中,所有控制器都包含在app.controller中,所有服务都包含在app.service等中。
为了进一步复杂化,在该指令中定义的控制器具有单个依赖关系,并且它包含使$ http请求在$范围上设置值的函数。我知道我可以使用$ httpBackend mock来模拟这个依赖关系来模拟$ http调用,并将适当的对象返回给这个函数的调用。我已经在我创建的其他单元测试中做了这么多次,并且非常了解这个概念。
下面的代码是用CoffeeScript编写的。
这是我的指令:
angular.module('app.directive') .directive 'exampleDirective',[() -> restrict: 'A' templateUrl: 'partials/view.html' scope: true controller: ['$scope','Service',($scope,Service) -> $scope.model = {} $scope.model.value_one = 1 # Call the dependency Service.getValue() .success (data) -> $scope.model.value_two = data .error -> $scope.model.value_two = 0 ] ]
这是依赖服务:
angular.module("app.service") .factory 'Service',['$http',($http) -> getValue: () -> options.method = "GET" options.url = "example/fetch" $http _.defaults(options)
这是视图:
<div> {{model.value_one}} {{model.value_two}} </div>
我已经简化了这一点,因为我的目标只是要了解如何连线,我可以从那里拿走。我以这种方式构造它的原因是因为我最初没有创建这个。我正在为现有项目编写测试,而我无法以其他方式进行配置。我试图写测试,但不能让它做我想要的。
我想测试一下这些值是否绑定到视图,如果可能的话,还可以测试一下控制器是否正确地创建值。
这是我所得到的:
'use strict' describe "the exampleDirective Directive",-> beforeEach module("app.directive") beforeEach module("app/partials/view.html") ServiceMock = { getValue : () -> options.method = "GET" options.url = "example/fetch" $http _.defaults(options) } #use the mock instead of the service beforeEach module ($provide) -> $provide.value "Service",ServiceMock return $httpBackend = null scope = null elem = null beforeEach inject ($compile,$rootScope,$injector) -> # get httpBackend object $httpBackend = $injector.get("$httpBackend") $httpBackend.whenGET("example/fetch").respond(200,"it works") #set up the scope scope = $rootScope #create and compile directive elem = angular.element('<example-directive></example-directive>') $compile(elem)(scope) scope.$digest()
我不知道我有多近,或者如果这是正确的。我想要能够断言值正确地绑定到视图。我使用Vojtajina的例子来在我的karma.js文件中设置html2js,以便我抓住这些观点。我做了很多研究来找到答案,但是我需要一些帮助。希望一个程序员比我能指出正确的方向更聪明。谢谢。
在业务中创建元素,然后使用您的指令名称的
.controller()
函数来抓取控制器。例如,用最后几行替换这些行:
elem = angular.element('<div example-directive></div>'); $compile(elem)($rootScope); var controller = elem.controller('exampleDirective');
请注意,根据您如何定义您的指令,它应该是按属性而不是元素。我也不是100%肯定,但我不认为你需要的范围。$ digest;通常我只是把任何需要应用到范围的东西。$ apply(function(){})block。