#reactjs #jestjs #react-testing-library #jest-dom
Вопрос:
Я работаю над тестовым кодом для своего проекта 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. Кто-нибудь знает, почему toHaveValue
и debug
показывают разные результаты?
Комментарии:
1. Как вы можете видеть из вашего собственного журнала отладки, начальное значение-это не
0
«но"0"
«. Это строка, а не число2. @lbsn даже когда все работает хорошо и возвращает целое
0
число , он показывает вам"0"
debug()
результат, потому что он написан в html-форме. и даже если фактический результат таков"0"
, это не имеет смысла, что вы получаетеnull
в результате.
Ответ №1:
После некоторого копания выясняется, что это действительно ожидаемое поведение toHaveValue
в случае <input type="number">
.
Во-первых, входное значение при вводе строки (в случае type="number"
) на самом деле является пустой строкой:
Алгоритм очистки значений выглядит следующим образом: если значение элемента не является допустимым числом с плавающей запятой, вместо этого установите его в пустую строку.
В то время screen.debug()
как будет выводиться дерево DOM, вы можете проверить фактическое 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("");
Комментарии:
1. вау. Я даже не заботился о самой спецификации ввода. такое милое объяснение. большое спасибо 🙂