Библиотека испытаний реагирует берет радость и возможности тестирования на следующий уровень.
Сегодня я столкнулся с делом на работе, где я хотел утверждать условную всплеску инструментов. Подсказка должна отображаться только в том случае, если текст метки переполнен и отрезан эллипсисом.
Вот упрощенная реализация того, что я сделал.
import * as React from 'react';
import { Tooltip } from 'Tooltip';
// text overflow is triggered when the scroll width
// is greater than the offset width
const isCutOff = (node: T | null) =>
(node ? node.offsetWidth < node.scrollWidth : false);
export const useIsTextCutOff = (
ref: React.RefObject
): [boolean, () => void] => {
// since the ref is null at first, we need a stateful value
// to set after we have a ref to the node
const [isTextCutOff, setIsTextCutOff] = React.useState(
isCutOff(ref.current)
);
// allow the caller to refresh on account of refs being
// outside of the render cycle
const refresh = () => {
setIsTextCutOff(isCutOff(ref.current));
};
return [isTextCutOff, refresh];
};
interface Props {
href: string;
label: string;
}
export const NameRenderer: React.FC = ({
label,
href
}) => {
const labelRef = React.useRef(null);
const [isTextCutOff, refresh] = useIsTextCutOff(labelRef);
return (
);
};
Потому что ref.current Значение начинается как нулевой Я не могу вычислить ширину на начальном рендере. Чтобы решить эту проблему, я использовал Onmouseenter Событие, чтобы проверить ширину элемента, как только кто -то на самом деле зависает от этого. Мы можем быть уверены ref.current будет определен к тому времени.
Кипарис Было бы отличным способом проверить это, но экран, который я нахожусь в этом контексте, требует установки AUTH и конкретных тестовых данных, которые легче сделать на уровне теста интеграции компонентов.
Ключ здесь состоит в том, чтобы вмешаться в то, как реагирует реагирование ref реквизит. С крючками вы просто назначаете имя React.useref (null) Результат и передайте это на узел, как Анкет
Когда вы осматриваете ширину этого виртуального узла, вы получите большой жир 🍩. Нет на самом деле окрашенного элемента с шириной для измерения.
Так , мы шпионим на React.useref с Jest.spyon и использовать получить и установить Функции от хорошего JavaScript Getter и сеттеры Анкет
import * as React from 'react';
import * as utils from '@testing-library/react';
import user from '@testing-library/user-event';
import { NameRenderer } from '.';
describe('Components: NameRenderer', () => {
const props = {
href: "blah blah",
label: "halb halb",
};
type NodeWidth = Pick<
HTMLElement,
'offsetWidth' | 'scrollWidth'
>;
const setMockRefElement = (node: NodeWidth): void => {
const mockRef = {
get current() {
// jest dom elements have no width,
// so mocking a browser situation
return node;
},
// we need a setter here because it gets called when you
// pass a ref to
set current(_value) {},
};
jest.spyOn(React, 'useRef').mockReturnValue(mockRef);
};
it('shows a tooltip for cutoff text', async () => {
setMockRefElement({ offsetWidth: 1, scrollWidth: 2 });
const { getByRole } = utils.render(
);
const checklist = getByRole(
'link',
{ name: new RegExp(props.label) }
);
expect(utils.screen.queryByRole('tooltip'))
.not.toBeInTheDocument();
user.hover(checklist);
expect(utils.screen.getByRole('tooltip'))
.toBeInTheDocument();
user.unhover(checklist);
await utils.waitForElementToBeRemoved(
() => utils.screen.queryByRole('tooltip')
);
});
afterEach(() => {
jest.resetAllMocks();
});
});
SetMockRefelement Утилита позволяет легко проверить различные вариации OffsetWidth к ScrollWidth соотношение. С этой визуальной частью спецификации насмехается, мы можем вернуться к прекрасным API -интерфейсам и пользовательским событиям, представленным нам путем тестирования библиотеки.
Вот полная демонстрация.
Оригинал: “https://dev.to/tmikeschu/testing-element-dimensions-without-the-browser-5532”