javascript - 开 Jest : Compare DOM element with JavaScript Object

标签 javascript html object jestjs

我有一个包含许多输入的 HTML 模板,如下所示:

<form action="/action_page.php">
  <label for="fname">First name</label>
  <input type="text" id="fname" value={person.firstName} disabled={isInViewMode}>
  <label for="lname">Last name</label>
  <input type="text" id="lname" value={person.lastName} disabled={isInViewMode}>
  ...
</form>

我可以像这样检查 DOM 中的内容...

const inputs = document.querySelectorAll("input");
expect(inputs[0].type).toBe("text");
expect(inputs[0].value).toBe("John");
expect(inputs[0].disabled).toBe(false);

这可行,但很多时候,我更喜欢使用 JavaScript 对象来定义我的期望,而不是重复 expect(...).toBe(...),如下所示:

const expectedInputs = [
  { type: "text", value: "John", disabled: false },
  ...
];

我可以像这样对 expectedInputs 做出断言:

const inputs = document.querySelectorAll("input");
expectedInputs.forEach((expectedInput, idx) => {
  Object.getOwnPropertyNames(expectedInput).forEach(key => {
    expect(inputs[idx][key].toBe(expectedInput[key]);
  }
});

在使用test.each的场景中,这对于避免冗长的测试代码很有用。但陷阱是,当某些事情失败时,我经常无法轻易地看到它在哪个预期的 DOM 元素上失败(因为我不再有一个特定于对象的行号可供引用):

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: undefined

  192 |         expectedInputs.forEach((input, idx) => {
  193 |             Object.getOwnPropertyNames(input).forEach(key => {
> 194 |                 expect(inputs[idx][key]).toBe(input[key]);
      |                 ^
  195 |             });
  196 |         });

如果我可以将整个 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 |         });

是否有某种方法可以 A) 将 HTMLElement 转换为可以使用 expect(...).toEqual(expect.objectContaining(...)) 进行比较的内容,或 B) 在这种情况下使用 Jest 获得更多信息的失败消息的其他一些不太复杂的方法?

最佳答案

我想我明白你在问什么。您想为此转动 HTMLElement

<input type="text" id="fname" value={person.firstName} disabled={isInViewMode}>

进入此

{type: "text", id: "fname", value: //...

您可以使用Element.attributes这是元素属性的集合。它不是一个数组——它是一个 NamedNodeMap所以你可以Array.from它 - 然后mapreduce到你想要的对象表示。

const input = document.getElementById("foo");
const obj1 = {};
Array.from(input.attributes)
    .map(attribute => {
    obj1[attribute.name]=attribute.value;
});

console.log(obj1); // {id: "foo", name: "bar", value: "baz"}

// or

const obj2 = Array.from(input.attributes)
    .reduce((acc, attr) => {
        acc[attr.name] = attr.value;
        return acc;
    }, {});
    
console.log(obj2);  // {id: "foo", name: "bar", value: "baz"}
<input id="foo" name="bar" value="baz">

关于javascript - 开 Jest : Compare DOM element with JavaScript Object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65690668/

相关文章:

javascript - 限制输入字段的多语言

javascript - 如何使用scrapy或selenium抓取动态页面?

java - 引用自身的类如何工作?

javascript - 如何在 javascript 中使用数组中的数据填充和对象

javascript - 如何淡化div中背景颜色之间的过渡?

javascript - AngularJS 按类别过滤

javascript - 在 javascript if 语句中放入 = 是不好的做法吗?

javascript - 加税 - Paypal 变量

javascript - 如何在div中添加对象

javascript - 使用 ng-click 或 jquery 检测平板电脑上的长按