【问题标题】:How to unit test an A-Frame component with Qunit?如何使用 Qunit 对 A-Frame 组件进行单元测试?
【发布时间】:2017-04-30 13:33:22
【问题描述】:

假设我们有一个基本的 A-Frame 组件:

AFRAME.registerComponent('scale-on-mouseenter', {
    schema: {
        to: {
            default: '2 2 2'
        }
    },
    init: function () {
        this.el.addEventListener('mouseneter', function () {
            this.setAttribute('scale', data.to);
        });
    }
});

我想通过 QUnit 进行测试。如何测试这个组件是否创建了scale属性?

我是否应该为此创建一个“测试 A-Scene”并验证 DOM?还是有更“单元”的测试方式?

【问题讨论】:

  • 是的,它很有帮助。谢谢你。我写了一个答案(但我仍然不确定我的方法是否适合 EventListener 部分。请随意写下你自己的答案,我接受它。

标签: javascript unit-testing qunit aframe


【解决方案1】:

这里提出的问题分为两部分。

  • 测试组件
  • 测试事件监听器

测试组件

ngokevin 提供的链接给出了解决方案。更特别的是,查看现有测试表明我们需要创建一个测试a-scene https://github.com/aframevr/aframe/blob/master/tests/components/scale.test.js

这并不是真正的单一测试,但是,嘿,我不想模拟所有的 A-Frame 库!

让我们从一个更基本的代码开始测试,没有EventListener

// Set a scale factor to 2 2 2
AFrame.registerComponent('big', {
    init: function () {
        this.el.setAttribute('scale', '2 2 2');
    }
});

关联的测试需要创建一个测试a-scene。我们可以使用QUnit.module

QUnit.module('Component testing', {
    before: function () {
        var scene = document.createElement('a-scene');
        document.querySelector('#qunit-fixture').appendChild(scene);
    },
    after: function () {
        var scene = document.querySelector('#qunit-fixture > a-scene'); 
        scene.parentNode.removeChild(scene);
    }
});

现在,我们可以通过创建a-entity 来测试组件,看看在组件添加到标签时是否创建了属性。我们只需要等待组件被加载。否则,断言是在组件加载之前进行的,最终会失败。

QUnit.test('Big add scale to 2 2 2', function (assert) {
    // Create the entity to test
    var entity = document.createElement('a-entity');
    entity.setAttribute('big', '');

    // Add it to the testing a-scene
    var scene = document.querySelector('#qunit-fixture > a-scene');
    scene.appendChild(entity);

    // Wait for the component to be loaded
    var done = assert.async()
    entity.addEventListener('loaded', function () {
        // Actual test
        assert.deepEqual(
            entity.getAttribute('scale'), 
            {'x': 2, 'y': 2, 'z': 2});
        done();
    });
});

测试事件监听器

最初的问题涉及EventListener。提醒一下,这是要测试的代码。

AFRAME.registerComponent('scale-on-mouseenter', {
    schema: {
        to: {
            default: '2 2 2'
        }
    },
    init: function () {
        this.el.addEventListener('mouseneter', function () {
            this.setAttribute('scale', data.to);
        });
    }
});

对此进行测试需要另一个技巧。一种解决方案是创建一个命名函数,然后将此函数作为处理程序添加到EventListener 中,如here 所述。测试将单独测试命名函数,而不是 addEventListener 部分。

第二种解决方案是使用setTimeout 技巧,如here 所述 .最终测试将使用之前的工作来测试组件,然后分派一个Event,然后使用setTimeout 中的assert 部分对测试进行排队。超时 0 效果很好。

QUnit.test('scale-on-mouseenter add eventlistener', function (assert) {
    // Create the entity to test
    var entity = document.createElement('a-entity');
    entity.setAttribute('scale-on-mouseenter', '');

    // Add it to the testing a-scene
    var scene = document.querySelector('#qunit-fixture > a-scene');
    scene.appendChild(entity);

    // Wait for the component to be loaded
    var done = assert.async()
    entity.addEventListener('loaded', function () {
        // Dispatch the event
        entity.dispatchEvent(new Event("mouseenter"));
        // Queue the test with a timeout of 0
        setTimeout(function () {
            // Actual test
            assert.deepEqual(
                entity.getAttribute('scale'), 
                {'x': 2, 'y': 2, 'z': 2});
            done();
        });
    });
});

【讨论】:

  • 不错。 Karma + Mocha 套件完全能够测试事件侦听器。如果你检查测试,有很多 addEventListeners 和 el.emits。您也可以使用entity.emit 发出事件。
  • 感谢您的提示。我坚持使用 QUnit,但看起来 Karma 也可用于 QUnit。无论如何,我没有很多 EventListener 可以测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
  • 1970-01-01
相关资源
最近更新 更多