Использование HTMLElement

Цель

В этом примере я хотел показать вам, как вы можете погрузиться в DOM, чтобы найти элементы в ваших шаблонах Angular. Это можно использовать, чтобы убедиться, что ваши директивы Angular работают правильно при написании тестов. Для этого мы воспользуемся возможностями API HTMLElement. Это позволит управлять и читать свойства элементов в шаблоне HTML нашего компонента.

* ПРИМЕЧАНИЕ. Эта статья не является полноценным руководством по тестированию в Angular. Для получения дополнительной информации попробуйте this.

Что дает вам модуль тестирования Angular

По умолчанию в Angular есть несколько отличных служебных классов, которые можно использовать при написании тестов. Их можно в основном импортировать из @angular/core/testing, однако есть и другие инструменты, которые вы можете использовать, например класс By, который также можно использовать для запроса к DOM. Его можно найти в @angular/platform-browser.

Основной класс, который мы будем обсуждать в этом примере, - это класс ComponentFixture. Этот класс действует как оболочка для нашего фактического компонента с некоторым дополнительным поведением. У Fixture есть свойство, которое представляет HTML-код компонента как nativeElement, что нам и нужно, чтобы начать взаимодействие с DOM.

Чтобы воспользоваться этой возможностью, нам сначала нужно создать нашу директиву для тестирования.

Здесь мы видим простую директиву, которая выполняет только одно действие. Он переключает регистр текста. Для этого он импортирует класс ElementRef и использует этот API для получения nativeElement компонента хоста. Это важный шаг, который показывает нам, куда нам нужно заглянуть позже при тестировании этой директивы. Использование декоратора @HostListener() дает нам возможность слушать события, а затем реагировать.

Доступ к DOM

Теперь у нас есть настройка директивы, и мы готовы ее протестировать! Давайте посмотрим на готовый тестовый файл, а затем разберем его по частям.

Я добавил несколько комментариев в код, чтобы показать, что я пытаюсь сделать.

Давайте начнем сверху и спустимся вниз.

Как видите, мы импортируем все необходимое для этого. Во-первых, поскольку это файл спецификации, нам нужно импортировать классы тестирования, такие как TestBed и ComponentFixture. Мы также импортируем нашу директиву, потому что без нее ее довольно сложно протестировать. Затем, наконец, мы импортируем несколько базовых классов сборки Angular, которые помогут нам создать наш тестовый компонент.

Создание тестового компонента

Иногда мы хотим протестировать директиву, но нам не нужно тестировать ее на реальном компоненте. В этом случае мы можем просто создать тестовый компонент в нашем файле спецификации, как здесь.

Это позволяет нам не импортировать ненужные зависимости и не беспокоиться о создании ненужных заглушек. Этот компонент может оставаться очень простым и по-прежнему позволять нам тестировать директиву. Однако, чтобы помочь нам в дальнейшем проиллюстрировать этот урок, мы добавляем свойство clickCount в этот компонент, чтобы помочь нам отслеживать, сколько кликов произошло на компоненте. Это только в демонстрационных целях.

Испытательная установка

Теперь у нас есть TestComponent, и мы можем приступить к настройке нашего теста. Сначала мы создаем блок describe для размещения нашей тестовой логики. Затем мы создаем две очень важные ссылки, компонент и приспособление этого компонента. Помните, что приспособление - это просто оболочка компонента.

Затем внутри beforeEach() мы инициализируем тестовый модуль. Единственное, что здесь следует отметить, это то, что мы объявляем только TestComponent и CapitalizeDirective.

Наконец, мы создаем новый экземпляр этого компонента и устанавливаем переменную component.

Чего ожидать ()… при ожидании

Когда все настроено, мы, наконец, можем приступить к тестированию! :)

Прежде чем мы будем слишком взволнованы, давайте создадим тест на работоспособность, чтобы убедиться, что наш компонент действительно создается.

expect(component).toBeDefined();

Если это пройдет, мы знаем, что готовы к следующему тесту.

Совет от профессионала: пусть ng test работает, пока вы работаете, чтобы ничего не сломать.

Пришло время начать настоящее шоу. Нам нужно создать тест, чтобы убедиться, что этот компонент выполняет то, для чего он предназначен. В частности, когда щелкают по ведущему элементу, он меняет регистр текста.

Для этого нам необходимо сделать следующее:

1: получить ведущий элемент

2: получить дочерний элемент с атрибутом директивы

3. Запуск события клика

4. Убедитесь, что свойства этого элемента изменились.

Мы можем получить элемент хоста, также называемый debugElement, покопавшись в фикстуре.

const debugEl: HTMLElement = fixture.debugElement.nativeElement;

Обратите внимание на самый конец этой строки. Мы не просто останавливаемся на элементе отладки, мы идем еще дальше и получаем nativeElement и this - секрет доступа к DOM.

Получив доступ к собственному элементу, мы можем «ввести» debugEl как HTMLElement. Что открывает весь API для этого объекта.

Однако есть проблема. У нас нет нужного элемента! На самом деле нам нужен дочерний элемент <p>, на котором действительно есть директива. Для этого мы используем метод HTMLElement querySelector(), который принимает параметр селектора CSS и возвращает первый соответствующий элемент. В нашем случае это именно то, что мы хотим.

Пора нажимать!

HTMLElements имеет метод click(), который позволяет программно запускать событие щелчка.

p.click();

Это заставит наш компонент реагировать точно так же, как если бы пользователь щелкнул по нему. Единственная загвоздка в том, что нам нужно вручную запустить цикл обнаружения изменений Angular, чтобы зарегистрировать это изменение. Для этого мы делаем:

fixture.detectChanges();

Наконец, нам нужно убедиться, что все обновляется соответствующим образом. Нам нужно проверить две основные вещи: наш счетчик кликов увеличился, и текст теперь заглавными.

Проверить свойство компонента очень просто, используя ссылку на компонент, которую мы создали ранее.

expect(component.clickCount).toEqual(1);

Jasmine дает нам отличные вспомогательные методы, такие как toEqual(), чтобы сказать то, что мы хотим, на почти простом английском языке.

Затем, наконец, что не менее важно, мы проверяем стиль в нашем элементе абзаца, чтобы убедиться, что текст внутри него написан в верхнем регистре.

expect(p.style.textTransform).toBe('uppercase');

Если вы не знакомы с HTMLElement, каждый элемент имеет набор свойств, которые вы можете получить / установить. В этом случае мы хотим проверить список стилей для этого элемента, а затем убедиться, что значение для text-transform указано в верхнем регистре.

Наш последний тест - это в основном то же самое, с одной небольшой разницей. Мы хотим убедиться, что он действительно переключает регистр текста при нажатии.

Все тесты пройдены!

Теперь, когда у нас все настроено, мы можем запустить наше приложение с ng serve, затем мы можем запустить наши тесты с ng test и убедиться, что все наши спецификации проходят! Отлично.

ВОТ ЭТО ДА!!!!!!!!

Мы сделали действительно классные вещи!

Надеюсь, вы узнали о том, как использовать HTMLElement, чтобы копаться в ваших компонентах, чтобы проверить любые изменения свойств, которые вы вносите в DOM. Когда у вас есть элемент, вы можете делать все, что захотите. Дайте мне знать, если у вас есть лучший способ сделать это, или я допустил ошибки.

Полный код можно найти здесь.