在JavaScript对象创建后,如何使用Mocha / Chai开始检查DOM元素?

时间:2015-11-25 17:41:32

标签: javascript mocha chai

我需要使用setTimeout吗? (当我这样做时它会起作用)。我遇到的问题是FeedObject进行异步调用,所以当创建它的新实例时,它需要一段时间才能将自己注入到DOM中。

describe('Default Case', function () {
            before(function () {
                $divHolder = $('#divHolder');
                $divHolder.html('');
                var myComponent = new FeedObject({
                    div: $divHolder[0],
                    prop: {
                        id: 'myFeed',
                    },
                    client: {}
                });

                myComponent.createDOMElements();
            });
            it('should exist', function () {
                console.log($divHolder.find('.feed-item')); // This does not exist unless I use a timeout
            });

编辑:为了澄清一下,new FeedObject进行了一次AJAX通话。

3 个答案:

答案 0 :(得分:0)

完成new FeedObject时需要确定的内容。取决于FeedObject提供的内容,它可能意味着:

  • 提供在new FeedObject完成时调用的回调。在回调中拨打done

  • 收听事件(很可能是自定义jQuery事件)。在事件处理程序中调用done

  • 使before挂钩返回new FeedObject返回的对象上存在的promise。例如,ready字段可以包含此承诺,您可以执行return myComponent.ready。摩卡将等待承诺得到解决。 (从done挂钩中删除before参数。)

我强烈建议您添加上述设施之一,而不是使用setTimeoutsetTimeout的问题在于它始终不是最理想的:要么等待比DOM准备好所需的时间更长,要么设置超时,这超出了准备就绪的实际时间,但在某些情况下例如,超时时间太短(例如,如果您的机器出现活动峰值而没有为运行测试代码的浏览器留下足够的CPU),并且由于虚假原因,测试将失败。

答案 1 :(得分:0)

setTimeOut将起作用(直到服务器响应时间超过您指定的时间,然后它将无法工作),但它绝对不是最佳或最快的方式。当您使用异步调用时,需要定义一个在代码完成后运行的回调方法。代码的想法应该是这样的:

describe('Default Case', function () {
  // Your code goes here

  $.ajax = function(ajaxOpts)
  {
    var doneCallback = ajaxOpts.done;
    doneCallback(simulatedAjaxResponse);
  };

  function fetchCallback(user)
  {
    expect(user.fullName).to.equal("Tomas Jakobsen");
    done();
  };

  fetchCurrentUser(fetchCallback);
});

如果您需要更多详细信息,可以查看这个非常有用的link。希望有所帮助!

答案 2 :(得分:0)

我会使用这个async chai plugin。如果您使用promise api(可能是处理异步测试的最straight-forward方式),这使得测试异步操作非常简单。您只需要记住return任何异步调用(或返回一个承诺),以便chai知道在等待之前“等待”。

describe(() => {
  let sut
  beforeEach(() => {
    sut = new FeedObject()
    return sut.createDomElements() // <- a promise
  })
  it('should exist', () => {
    $('#target').find('.feed-item').should.exist
  })
})

还要考虑这个测试的目标:你为什么要这样做?我发现很多DOM插入/删除/存在测试都是浪费精力。如果您将第三方库/框架作为应用程序代码的一部分进行测试,则尤其如此。证据负担在库/框架上以证明它是正确的(并且大多数编写良好的库已经有一个测试套件),而不是你的应用程序。如果你担心测试“我是否正确调用了这个第三方代码”,那么有更好的方法可以在不触及DOM的情况下进行测试。