Jest:将DOM元素与JavaScript对象进行比较
我有一个包含许多输入的HTML模板,如下所示:Jest:将DOM元素与JavaScript对象进行比较,javascript,html,object,jestjs,Javascript,Html,Object,Jestjs,我有一个包含许多输入的HTML模板,如下所示: 名字 姓 ... 我可以检查DOM中的内容,就像这样 const inputs=document.querySelectorAll(“输入”); expect(输入[0].type).toBe(“文本”); expect(输入[0].value).toBe(“John”); expect(输入[0]。已禁用)。toBe(false); 这是可行的,但通常不是重复expect(…)。为了(…),我更喜欢使用JavaScript对象来定义我的期望
名字
姓
...
我可以检查DOM中的内容,就像这样
const inputs=document.querySelectorAll(“输入”);
expect(输入[0].type).toBe(“文本”);
expect(输入[0].value).toBe(“John”);
expect(输入[0]。已禁用)。toBe(false);
这是可行的,但通常不是重复expect(…)。为了(…)
,我更喜欢使用JavaScript对象来定义我的期望,如下所示:
const expectedInputs=[
{type:“text”,value:“John”,disabled:false},
...
];
我可以这样断言expectedInputs
:
const inputs=document.querySelectorAll(“输入”);
expectedInputs.forEach((expectedInput,idx)=>{
Object.getOwnPropertyNames(expectedInput).forEach(key=>{
expect(输入[idx][key].toBe(expectedInput[key]);
}
});
这有助于避免在使用等场景中出现冗长的测试代码。但陷阱在于,当某些东西失败时,我通常无法看到它在哪个预期DOM元素上失败(因为我不再有对象特定的行号可供参考):
如果我可以将整个JS对象与DOM元素对象进行比较,这将得到解决。但我很难理解如何表示HTMLElement
,以便将其与普通JS对象进行比较。例如,我尝试使用object.assign()
使用HTMLElement
的属性创建JS对象。但是我没有在结果对象上获得正确的属性:
expect(received).toEqual(expected) // deep equality
Expected: ObjectContaining {"disabled": true, "tagName": "INPUT", "type": "text", "value": "John"}
Received: {"$fromTemplate$": true, "$shadowResolver$": undefined, Symbol(SameObject caches): {"classList": {"0": "slds-p-vertical_none"}}}
192 | expectedInputs.forEach((expectedInput, idx) => {
193 | const inputObj = Object.assign({}, inputs[idx]);
> 194 | expect(inputObj).toEqual(expect.objectContaining(expectedInput));
| ^
195 | });
有什么方法可以将
HTMLElement
转换为可以使用expect(…).toEqual(expect.objectContaining(…)
进行比较的内容,或者B)在这种情况下使用Jest实现更具信息性的失败消息的其他不太复杂的方法吗?我想我理解你的要求。您想为此打开HTMLElement
进入这个
{type:“text”,id:“fname”,value://。。。
您可以使用,它是元素属性的集合。它不是数组--它是一个数组,因此您可以数组。从它--然后将映射到或减少到所需的对象表示形式中
const input=document.getElementById(“foo”);
常量obj1={};
Array.from(input.attributes)
.map(属性=>{
obj1[attribute.name]=attribute.value;
});
console.log(obj1);//{id:“foo”,name:“bar”,value:“baz”}
//或
const obj2=Array.from(input.attributes)
.减少((acc,attr)=>{
acc[属性名称]=属性值;
返回acc;
}, {});
console.log(obj2);//{id:“foo”,name:“bar”,value:“baz”}
我在JSBin中进行了测试,而这个概念实际上在一个普通的JS环境中工作。请看……所以,投票表决吧!我的问题是,在我的实际场景中(用笑话测试Salesforce Lightning Web组件),大多数属性都可以通过HTMLElement中的点符号访问(例如值,禁用)出于某种原因,不要通过input.attributes
显示。我不确定这会是什么情况。作为记录,我现在非常确定我的Salesforce特定问题与本主题中讨论的内容有关:虽然我认为你已经有效地回答了这个问题,但我已经打开了一个新的主题来澄清我真正的问题,现在我已经取消了这个主题理解IDL属性,而不是内容属性:IDL属性很有趣。对于包含expectedInputs
的对象,以及给定元素input
的对象,让expectedInputs
中的键映射到input
元素上的值怎么样这obj3=Object.keys(expectedInputs).reduce((acc,attr)=>{acc[attr.name]=input[attr.name];return acc;},{});
这是我没有想到的另一个解决方案。很好!
expect(received).toEqual(expected) // deep equality
Expected: ObjectContaining {"disabled": true, "tagName": "INPUT", "type": "text", "value": "John"}
Received: {"$fromTemplate$": true, "$shadowResolver$": undefined, Symbol(SameObject caches): {"classList": {"0": "slds-p-vertical_none"}}}
192 | expectedInputs.forEach((expectedInput, idx) => {
193 | const inputObj = Object.assign({}, inputs[idx]);
> 194 | expect(inputObj).toEqual(expect.objectContaining(expectedInput));
| ^
195 | });