我正在尝试测试Angular指令,但我不确定为什么我的测试没有通过。我真的很感激一些额外的眼睛,以帮助我解决这个问题。
正在测试的指令是一个验证指令,它将验证元素的值是否与通过属性传入的id匹配的元素:
angular.module('app')
.directive('mustMatch', ->
restrict: 'A'
require: 'ngModel'
link: (scope, element, attrs, ctrl) ->
# I've tried both of these, traversal vs selection, neither work under test
#matchedElement = element.parents('form').find attrs.mustMatch
matchedElement = $(attrs.mustMatch)
ctrl.$parsers.unshift (val) ->
if val is matchedElement.val()
ctrl.$setValidity 'mustMatch', true
return val
else
ctrl.$setValidity 'mustMatch', false
return undefined
)
这是我的测试设置:
describe 'Directive: mustMatch', ->
scope = null
element = null
form = null
beforeEach module 'app'
beforeEach inject ($compile, $rootScope) ->
scope = $rootScope.$new()
scope.model = text1: '', text2: ''
element = angular.element '''<form name="someForm">
<input type="text" name="text1" ng-model="model.text1" id="text1"/>
<input type="text" name="text2" ng-model="model.text2" must-match="#text1"/>
</form>'''
$compile(element)(scope)
scope.$digest()
form = scope.someForm
it 'should fail validation if values do not match', ->
form.text1.$setViewValue 'some text'
form.text2.$setViewValue 'some other text'
expect(scope.model.text2).toBe undefined
expect(form.text2.$valid).toBe false
# TODO: Why isn't this passing? Is the matched element not being found?
it 'should pass validation if values match', ->
value = 'some text'
form.text1.$setViewValue value
form.text2.$setViewValue value
expect(scope.model.text2).toBe value
expect(form.text2.$valid).toBe true
第一个测试通过正常,但第二个测试返回undefined
/ false
,未达到测试期望。 同样,该指令在浏览器中运行良好,但第二次单元测试给了我一些问题。
我的karma.conf.js
文件中有jQuery,因为我的应用程序依赖于Bootstrap和其他一些jQuery插件。我有其他使用相同方法的指令测试。我的理论是指令中的元素选择在测试中不能正常工作。我吠叫正确的树吗?还有其他我想念的东西吗?
提前致谢!
更新
仍然遇到问题,但我相信我已经将问题隔离到我正在做的DOM遍历以获得匹配元素。如果我替换该指令的链接函数的这一行......
if val is matchedElement.val()
......用这条线......
if val is 'some text'
我可以通过测试。所以这告诉我链接函数的element
参数的值可能不是我在测试时期望的那样。
答案 0 :(得分:0)
在浪费了几个小时撕掉我的头发并尝试不同的修复之后,我偶然发现了问题的答案。我的问题出在beforeEach
函数中。 我没有将model.text1
设置为我期望验证的值。这是我更新的测试:
describe 'Directive: mustMatch', ->
scope = null
element = null
form = null
beforeEach module 'app'
beforeEach inject ($compile, $rootScope) ->
scope = $rootScope.$new()
# Setting `model.text1` to 'some text' fixed my problem
scope.model = text1: 'some text', text2: ''
element = angular.element '''<form name="someForm">
<input type="text" name="text1" ng-model="model.text1" id="text1" />
<input type="text" name="text2" ng-model="model.text2" id="text2" must-match="#text1" />
</form>'''
$compile(element)(scope)
scope.$digest()
form = scope.someForm
form.text1.$setViewValue 'some text'
it 'should fail validation if values do not match', ->
form.text2.$setViewValue 'some other text'
expect(scope.model.text2).toBe undefined
expect(form.text2.$valid).toBe false
it 'should pass validation if values match', ->
form.text2.$setViewValue 'some text'
expect(scope.model.text2).toBe 'some text'
expect(form.text2.$valid).toBe true