如何使用 Qunit 对 A-Frame 组件进行单元测试?
How to unit test an A-Frame component with Qunit?
假设我们有一个基本的 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
属性?
我是否应该为此创建一个 "testing A-Scene" 并验证 DOM?或者有更多的"unit"测试方法吗?
这里提出的问题分为两部分。
- 正在测试组件
- 测试 EventListener
正在测试组件
ngokevin提供的link给出了解决方案。更具体地说,查看现有测试表明我们需要创建一个测试 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
原来的问题涉及一个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();
});
});
});
假设我们有一个基本的 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
属性?
我是否应该为此创建一个 "testing A-Scene" 并验证 DOM?或者有更多的"unit"测试方法吗?
这里提出的问题分为两部分。
- 正在测试组件
- 测试 EventListener
正在测试组件
ngokevin提供的link给出了解决方案。更具体地说,查看现有测试表明我们需要创建一个测试 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
原来的问题涉及一个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();
});
});
});