【问题标题】:Jest: Compare DOM element with JavaScript Object笑话:比较 DOM 元素和 JavaScript 对象
【发布时间】:2021-01-12 19:22:01
【问题描述】:

我有一个包含许多输入的 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 获得更多信息的失败消息场景?

【问题讨论】:

    标签: javascript html object jestjs


    【解决方案1】:

    我想我明白你在问什么。你想为此转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"}
    &lt;input id="foo" name="bar" value="baz"&gt;

    【讨论】:

    • 我在 JSBin 中测试过,这个概念实际上适用于 vanilla JS 环境。见jsbin.com/xedatog/3/edit?html,js,output ...所以,赞成!我的问题是,在我的实际场景中(使用 Jest 测试 Salesforce Lightning Web 组件),大多数可以通过 HTMLElement 中的点符号访问的属性(例如valuedisabled)不会通过 @ 显示987654338@ 出于某种原因。我不确定这是怎么回事。
    • 作为记录,我现在很确定我的 Salesforce 特定问题与此线程中讨论的内容有关:salesforce.stackexchange.com/questions/264202
    • 虽然我认为你已经有效地回答了这个问题,但我已经开辟了一个新线程来澄清我的真正问题,我现在明白这是关于 IDL 属性,而不是内容属性:stackoverflow.com/questions/65693648
    • IDL 很有趣。那么对于具有您的expectedInputs 和给定元素input 的对象来说,只需制作一个将expectedInputs 中的键映射到input 元素上的值的对象,就像这样obj3 = Object.keys(expectedInputs).reduce((acc,attr)=&gt;{acc[attr.name]=input[attr.name];return acc;},{});
    • 这是另一个我没有想到的解决方案。不错!
    猜你喜欢
    • 1970-01-01
    • 2021-07-31
    • 2014-11-02
    • 2011-10-21
    • 2020-04-30
    • 2011-11-06
    • 2012-05-01
    • 1970-01-01
    • 2011-06-12
    相关资源
    最近更新 更多