javascript - JQuery 检查笑话测试中的元素可见性
问题描述
我正在尝试在单元测试中检查元素可见性状态是否已更改。我正在.is(":visible")
这样做,在单元测试中它总是报告该元素是隐藏的,但它在浏览器中工作正常。
代码就这么简单(参见完整工作示例):
html
<form>
<div id="field">hi</div>
<input type='checkbox' id="toggle">toggle</input>
<input type='checkbox' id="show">show</input>
<input type='checkbox' id="hide">hide</input>
</form>
javascript
$('form').on('change', 'input#toggle[type="checkbox"]', function() {
target_row = $('#field');
if (target_row.length) {
target_row.toggle("fast");
}
});
正如我所写,这在浏览器中运行良好,但在以下测试中不起作用:
jest.dontMock('jquery');
jest.dontMock('../toggle.js');
$ = jQuery = require('jquery');
describe('toggle.js', function() {
var sut = require('../toggle.js');
function givenFields(formFields) {
document.documentElement.innerHTML = `
<html><body><form>
<div id="field">hi</div>
${formFields}
</form></body></html>
`;
sut.initialize();
}
it('toggles the field', function() {
givenFields(`<input type='checkbox' id="toggle">toggle</input>`);
var initiallyVisible = $("#field").is(":visible");
$('#toggle').click();
// Checking that this is not jsdom rendering issue
expect(document.hidden).toEqual(false);
expect($("#field").is(":visible")).toEqual(!initiallyVisible);
});
it('shows the field', function() {
givenFields(`<input type='checkbox' id="show">show</input>`);
$('#show').click();
expect($("#field").is(":visible")).toEqual(true);
});
});
结果是:
● toggle.js › toggles the field
expect(received).toEqual(expected)
Expected: true
Received: false
26 | expect(document.hidden).toEqual(false);
27 |
> 28 | expect($("#field").is(":visible")).toEqual(!initiallyVisible);
| ^
29 | });
30 |
31 | it('shows the field', function() {
at Object.toEqual (src/__test__/toggle.spec.js:28:40)
● toggle.js › shows the field
expect(received).toEqual(expected)
Expected: true
Received: false
34 | $('#show').click();
35 |
> 36 | expect($("#field").is(":visible")).toEqual(true);
| ^
37 | });
38 | });
39 |
at Object.toEqual (src/__test__/toggle.spec.js:36:40)
package.json
是:
{
"name": "toggle",
"devDependencies": {
"jasmine": "3.2.0",
"jest-cli": "24.1.0",
"jquery": "3.3.1"
},
"scripts": {
"test": "jest"
}
}
任何想法可能有什么问题,我该如何解决这个问题?
我不太喜欢的一个选项,因为它不是一个解决方案,但一种解决方法是我可以检查与 DOM 的交互而不是它的状态。我的意思是我可以验证对函数的调用toggle
,show
和hide
。这种方法有一个缺点,即它增加了复杂性,因为这需要我在测试中维护 DOM 元素的状态并引入关于初始状态的假设。
解决方案
我认为第一个问题是持续时间(在本例中为“快速”),切换和显示功能不仅会改变可见性:
当提供持续时间、普通对象或单个“完整”函数时,.toggle() 成为动画方法。.toggle() 方法同时为匹配元素的宽度、高度和不透明度设置动画。当这些属性在隐藏动画后达到 0 时,显示样式属性设置为 none,以确保元素不再影响页面的布局。
所以你实际上想要检查display
元素的。
下一个问题是 jquery 将显示设置为 200 毫秒none
,因此我们需要考虑这一点,这意味着我们可以编写如下内容:
it('toggles the field', function(done) {
givenFields(`
<div id="field">kuku</div>
<input type='checkbox' id="toggle">toggle</input>
`);
var initialDisplay = $("#field").css('display');
$('#toggle').click();
// Checking that this is not jsdom rendering issue
expect(document.hidden).toEqual(false);
var expectedDisplay = initialDisplay === 'block' ? 'none' : 'block'
setTimeout(function() {
expect($("#field").css('display')).toEqual(expectedDisplay);
done()
}, 200)
});
可能还有一种方法可以将jest timer-mocks注入到 jquery 中,这样您就可以避免 200 毫秒的等待。会很酷,但不确定是否可能。
编辑: jQuery.fx.off = true; 这很好用,给我们留下:
jest.dontMock('jquery');
jest.dontMock('./toggle.js');
$ = jQuery = require('jquery');
jQuery.fx.off = true;
describe('toggle.js', function() {
var sut = require('./toggle.js');
function givenFields(formFields) {
document.documentElement.innerHTML = `
<html><body><form>${formFields}</form></body></html>
`;
sut.initialize();
}
it('toggles the field', function() {
givenFields(`
<div id="field">kuku</div>
<input type='checkbox' id="toggle">toggle</input>
`);
var initialDisplay = $("#field").css('display');
$('#toggle').click();
// Checking that this is not jsdom rendering issue
expect(document.hidden).toEqual(false);
var expectedDisplay = initialDisplay === 'block' ? 'none' : 'block'
expect($("#field").css('display')).toEqual(expectedDisplay);
});
it('shows the field', function() {
givenFields(`
<div id="field">kuku</div>
<input type='checkbox' id="show">show</input>
`);
$('#show').click();
expect($("#field").is(":visible")).toEqual(true);
});
});
推荐阅读
- r - 聚合 R 中的数据
- r - 使用 lapply 和 mapply 将列附加到数据框列表
- c++ - 读取 Quine-McKluskey 程序的数据
- kotlin - 类型推断仅适用于扩展功能
- python - 无法理解 Django 中 @login_required 的工作原理
- php - 是否有一个脚本命令可以使用 bash 脚本从 php 文件执行特定的 php 方法
- paypal - PayPal 是否接受美国运通的订阅?
- python - 如何旋转熊猫数据框?
- openlayers - OpenLayers 5 到 6:未渲染的图层
- c# - 使用 IOptions 检索 appsettings
在 ASP.NET Core 3.0 中