我正在开发一个使用ng-repeat制作表格的Angular应用程序。其中一个用户发现该表有时包含重复的条目,我在视觉上确认,然后立即写了一个Protractor测试。
在编写测试时,我注意到范围并没有以我理解的方式表现。
当然,第61行的for循环可以访问linkStorage
(第38行),因为它在更高的范围内。它记录了所有对象已通过第47行的promise中的for循环成功添加到对象中。
然而,当我在承诺之外移动确认循环时,比如说,expect
阻止之前......
...... linkStorage
是一个空对象。
循环对象找不到嵌套的键值对;它真的是空的。
为什么linkStorage
对象填充在then语句中,但不是在期望之前?
答案 0 :(得分:3)
第一个例子起作用是由于异步性。由于.getAttribute
方法是非阻塞的,因此代码在其工作时继续运行。因此,在填充对象之前到达控制台循环;它是空的。
如果你给异步代码一些时间来运行,可能是一秒钟:
... linkStorage
已填充。
将多个承诺链接在一起以确保代码在正确的时间运行。
it('should not have duplicates within the match grid', function() {
// Already on job A, with match grid shown.
var duplicate = false;
var linkStorage = {};
// Save unique links
var uniqueUserLinks = element.all(by.css('div.row table tbody tr td a'));
// get an array of href attributes
uniqueUserLinks.getAttribute('href')
.then(function(hrefs) {
// add the links to the linkStorage object
for (var i = 0; i < hrefs.length; i++) {
// if the link is already there
if( linkStorage[ hrefs[i] ] ) {
// update its counter
linkStorage[hrefs[i]] += 1
duplicate = true;
// there's already one duplicate, which will fail the test
break;
} else {
// create a link and start a counter
linkStorage[hrefs[i]] = 1;
}
};
}).then(function() {
// confirm links have been added to storage
for(var link in linkStorage) {
console.log('link:', link );
console.log('number:', linkStorage[link] );
}
}).then(function() {
expect(duplicate).toBe(false);
});
});