Angular-mocks digest不等待承诺

时间:2017-12-15 17:00:11

标签: angularjs promise angular-mock

我想要函数返回一个在加载DOM时解析的promise:

function waitForDom() {
  return $q((resolve) => {
    $window.addEventListener('DOMContentLoaded', () => {
      resolve("yay, i've loaded");
    });
  })
})

这在浏览器中运行良好。但是,当我尝试测试它时,测试永远不会完成,因为这个承诺永远不会解决:

it('some test', (done) => inject(($window, $q, $rootScope) => {
  waitForDom()
    .then(it => expect(it).toBe("yay, i've loaded"))
    .then(done);

  $rootScope.$digest();
}));

根据我对棱角分明的理解,承诺不会解决(和链接),直到你致电$digest。这使得您可以以同步方式测试角度。我知道了。但是,我在这里的示例应该完成,但由于某种原因它总是超时。

我已经尝试将resolve()置于$scope.$apply()内,但我已经及时#+; $摘要已经在进行中"。

我已经尝试将$digest置于setTimeout内,这也为我提供了一个已经在进行中的$ digest,我真的非常感到困惑。但那不是问题所在。

TLDR 如何让我的测试真正完成?

修改

虽然我可以解决上面的例子,但我正在寻找一个解决DOM事件监听器正文中的承诺的通用解决方案,如下所示:

function appendIframe() {
  return $q((resolve) => {
    const iframe = $window.document.createElement('iframe');
    const iframeParent = $window.document.body;

    iframe.src = authUrl;

    iframe.onload = function() {
      resolve('iframe loaded')
    };

    iframeParent.appendChild(iframe);
  });
})

不,用jqlite做这件事并没有什么不同。

1 个答案:

答案 0 :(得分:2)

使用angular.element

function waitForDom() {
  return $q((resolve) => {
    angular.element( () => {
      resolve("yay, i've loaded");
    });
  })
})

来自文档:

  

大多数浏览器以DOMContentLoaded事件的形式提供类似的功能。但是,jQuery的.ready()方法以一种重要且有用的方式不同:如果DOM准备就绪并且浏览器在代码调用.ready(handler)之前触发DOMContentLoaded,则仍将执行函数处理程序。相反,事件触发后添加的一个DOMContentLoaded事件侦听器永远不会被执行。