从QUnit调用时,调用trigger()并不总是触发 [英] Calling trigger() doesn't always fire when called from QUnit

查看:84
本文介绍了从QUnit调用时,调用trigger()并不总是触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然过去我曾经使用过QUnit,但是自从我真的使用过它已经有一年了,所以我希望这是微不足道的事情!

Although I've used QUnit in the past, it's been a year since I really used it, so I am hoping this is something trivial!

我有一个一堆QUnit测试工作得非常好,除了每次加载页面失败的测试。如果我刷新,测试工作,但如果我再次刷新它会中断!它变得可以预测,但我不明白为什么它不起作用。有问题的测试应使用触发器('更改')事件,但这只会每隔一次触发一次。

I have a bunch of QUnit tests that are working really well, apart from one that fails every other time that the page is loaded. If I refresh, the test works, but if I refresh again it breaks! It's become predictable but I cannot see why it's not working. The test in question should use a trigger('change') event, but this only fires every other time.

我有一个动态填充选择,我将更改事件绑定到。所有这一切都将值保存到 localStorage 并且测试我刚刚检查了该值已设置。

I have a dynamically populated select that I bind a change event to. All that it does it save the value to localStorage and the test I have just checks the value has been set.

示例HTML:

<select id="options">
    <option value="">Please choose</option>
</select>
<p id="result"></p>

示例JS:

$(document).ready(function() {
    var data = {
        1: 'Option 1',
        2: 'Option 2',
        3: 'Option 3'
    }
    for(var d in data) {
        $('#options').append($('<option>').val(d).text(data[d]));
    }
    $('#options').on('change', function() {
        $('#result').text(this.value);
        if(this.value != '') {
            localStorage.setItem('optionValue') = this.value;
        } else {
            throw 'You must choose a team';
        }
    });
});

示例QUnit测试:

test('Test some other stuff', function(assert) {
    localStorage.removeItem('optionValue');
    // some tests to check things have worked correctly
});

test('Is value added to localStorage?', 2, function(assert) {
    throws(function() { throw new $('#chooseTeam').val('').change(); }, 'No option selected');
    $('#options').val(1).trigger('change');
    equal(localStorage.getItem('optionValue'), 1, 'The first item should be selected');
});

然而,QUnit输出中的结果是 undefined 。我把它缩小到第一个测试,然后能够看到它是每次调用的行 localStorage.removeItem('optionValue'),但更改事件只是每隔一次都会触发。

However, the result in the QUnit output is undefined. I narrowed it down to the first test and then was able to see that it's the line localStorage.removeItem('optionValue') that is called every time but the change event is only triggered every other time.

我创建了一个JS小提琴,试图证明这个问题: http://jsfiddle.net/cchana/zqNtU/3/ (该演示展示了它应该如何工作,但不是失败的测试)

I've create a JS fiddle to try and demonstrate the problem: http://jsfiddle.net/cchana/zqNtU/3/ (the demo shows how it should work, but not the failing tests)

是否有明显会导致此失败的事情?

Is there something obvious that would make this fail anyway?

更新

以为我应该更新一些可能有用的信息...

Thought I should update with some information that may help...

在更改方法中,我添加了一个控制台.log(),如下所示:

In the change method, I added a console.log(), like so:

$('#options').on('change', function() {
    console.log('here');
});

我只想检查更改事件是否实际被触发,但正如测试显示的那样,该方法仅在每隔一次触发。

I just wanted to check that the change event was actually being triggered, but just as the tests show, the method is only triggered every other time.

更新2

获取我的测试通过,我删除了行 localStorage.removeItem('optionValue'); 不理想,如果可能的话,我仍然想要深究它!

To get my tests passing, I have removed the line localStorage.removeItem('optionValue'); not ideal and I would still like to get to the bottom of it if at all possible!

推荐答案

我从这篇文章(解决在qunit中交替失败测试背后的秘密)

I found the answer from this article (solving the mystery behind alternating failed tests in qunit)

为了解释原因,你可能有一个回调/插件自动绑定到页面上的现有元素。因此,当包含插件的文件包含在页面中时,元素会自动绑定。

To explain why, you probably have a callback/plugin automatically binds to existing elements on the page. So when the file containing the plugin is included in the page, the elements are binded automatically.

因此,当您第一次运行测试时,它会失败。为什么?!原因是当测试运行时,测试工具中的元素似乎在每次测试运行时都会重新创建。因此,当重新创建它们时,由于已经包含JavaScript文件,因此不会发生自动绑定。

So when you run the tests the first time, it fails. Why?! The reason is that when the tests are run, the elements in the test harness are seemingly re-created on each run of the tests. So when they are re-created, the automatic binding does not take place since the JavaScript file has already been included.

如果是这样,那么为什么它可以在备用调用上工作?啊......其中就是魔法。为了提高测试效率,QUnit将在页面刷新之前的其他测试之前运行失败的测试。因此,当在其他测试之前执行失败的测试时,测试工具中已经存在的元素被绑定,因此,测试通过!但是因为这些测试现在通过了,当页面刷新时它们会恢复到原来的顺序,因此它们现在就失败了!

If so, then why does it work on alternate invocations? Ah… therein lies the magic. To make tests more efficient, QUnit will run the failed tests before other tests upon page refresh. So, when the failed tests are executed before other tests, the elements in the test harness that are already present are binded, and thus, the tests PASS! But because these tests now pass, when the page is refreshed they go back to the same order as they originally was, and thus they now FAIL!

当然这个实现了,它促使我更有效地重写插件。希望这种自我发现对那里的人有所帮助!玩得开心测试!

Of course with this realization, it prompted me to rewrite the plugin more efficiently. Hope this self-discovery is helpful to someone out there! Have fun testing!

我希望这可以帮到你。

这篇关于从QUnit调用时,调用trigger()并不总是触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆