1

我正在为我的 React 项目编写测试代码。我要检查的是“如果输入类型是数字,则不允许插入文本”。下面是我写的测试代码。

it("disallow a text input", () => {
  const input = screen.getByLabelText(label0); // it has 0 as initial value
  const dummyText = "imyourfather";

  // typing a text won't change the value of input
  userEvent.type(input, dummyText);
  screen.debug();
  expect(input).toHaveValue(0); // FAILED -> return null
});

我在这里所期望的是获得初始值0,作为 的结果toHaveValue。但它实际上返回null

你可能会想'是的,你试图在数字类型的输入中插入一个文本,这就是它返回 null 的原因',但有趣的是它debug()并按我的预期console.log(input.value)返回。0

<!-- the result of debug() -->
<div
  class="ui input"
>
  <input
    id="form-field-number01"
    required=""
    type="number"
    value="0"
  />
</div>

而且,如果您手动尝试将文本值插入浏览器上的数字输入,它实际上会显示初始值 0。任何人都知道为什么toHaveValuedebug显示不同的结果?

4

1 回答 1

1

经过一番挖掘,看来这确实是toHaveValue万一的预期行为<input type="number">

首先,输入字符串时的输入值(在 的情况下type="number")实际上是一个空字符串

值清理算法如下:如果元素的值不是有效的浮点数,则将其设置为空字符串。

虽然将输出 DOM 树,但您可以在输入虚拟文本后通过记录它screen.debug()来检查实际属性:value

userEvent.type(input, dummyText);
console.log('--> Value: ', input.value);
console.log('--> Value type: ', typeof input.value);

现在,jest-dom 用来获取输入值的函数如下所示

function getInputValue(inputElement) {
  switch (inputElement.type) {
    case 'number':
      return inputElement.value === '' ? null : Number(inputElement.value)
    case 'checkbox':
      return inputElement.checked
    default:
      return inputElement.value
  }
}

如您所见,如果type="number"空字符串被解析为null. 不知道这背后的原因是什么。

至于您的具体情况,您可以测试输入元素以不将虚拟文本作为值或显示空值:

expect(input).not.toHaveValue(dummyText);
expect(input).toHaveDisplayValue("");
于 2021-10-01T08:57:34.953 回答