Vue test utils - Crash Course часть 2

Vue crush course

Условная отрисовка

Vue Test Utils предоставляет ряд функций для рендеринга и проверки состояния компонента с целью убедиться в его корректном поведении. В этой статье мы рассмотрим, как рендерить компоненты, а также проверять правильность отображения их контента.

Поиск элементов

Одна из самых основных особенностей Vue — это возможность динамически вставлять и удалять элементы с помощью v-if. Давайте посмотрим, как протестировать компонент, использующий v-if.

<!-- Nav.vue -->
<script setup>
import { ref } from 'vue'
const props = defineProps({
  admin: {
    type: Boolean,
    default: false
  }
})
</script>

<template>
  <nav>
    <a id="profile" href="/profile">My Profile</a>
    <a v-if="admin" id="admin" href="/admin">Admin</a>
  </nav>
</template>

В <Nav>компоненте отображается ссылка на профиль пользователя. Кроме того, если значение 
admin равно true, мы отображаем ссылку на раздел администрирования. Необходимо проверить корректность работы в трех сценариях:

  1. Ссылка /profile должна быть показана.
  2. Если пользователь является администратором, /admin ссылка должна отображаться.
  3. Если пользователь не является администратором, /admin ссылка не должна отображаться.

С использованием get()

wrapper Имеет метод get(), который ищет существующий элемент. Он использует 
querySelector синтаксис.

Мы можем проверить содержимое ссылки профиля, используя get():

test('renders a profile link', () => {
  const wrapper = mount(Nav)

  // Here we are implicitly asserting that the
  // element #profile exists.
  const profileLink = wrapper.get('#profile')

  expect(profileLink.text()).toEqual('My Profile')
})

Если функция  get() не возвращает элемент, соответствующий селектору, она выдаст ошибку, и ваш тест завершится неудачей. Функция  get() возвращает значение, DOMWrapper если элемент найден. — DOMWrapper это обертка вокруг элемента DOM, реализующая API Wrapper — именно поэтому мы можем выполнять действия profileLink.text() и получать доступ к тексту. Вы можете получить доступ к исходному элементу, используя свойство element.

import { mount } from '@vue/test-utils';
import { describe, it } from 'vitest';
import Nav from '@/components/Nav.vue';

describe('Nav.vue',()=>{
    it('Ссылка /profileдолжна быть показана', ()=>{
        const wrapper = mount(Nav);

        expect(wrapper.get('#profile').text()).toBe('My Profile');
    });

    it('администр, /admin ссылка должна отображаться', () => {
        const wrapper = mount(Nav,{
            props:{
                admin:true
            }
        });

        expect(wrapper.get('#admin').text()).toBe('Admin');
    });

    it('Не является администратором, /admin ссылка не должна отображаться', () => {
        const wrapper = mount(Nav, {
            props: {
                admin: false
            }
        });

        expect(wrapper.find('#admin').exists()).toBe(false);
    });

Если ищем элемент которого может и не быть как в последнем тесте, используем find ибо get выдаст ошибку.

Проверка видимости элементов

Иногда вам нужно просто скрыть/показать элемент, сохранив его в DOM. Vue предлагает решения 
v-show для таких сценариев.

<!-- Nav.vue -->
<script setup>
import { ref } from 'vue'

const shouldShowDropdown = ref(false)
<script>

<template>
  <nav>
    <a id="user" href="/profile">My Profile</a>
    <ul v-show="shouldShowDropdown" id="user-dropdown">
      <!-- dropdown content -->
    </ul>
  </nav>
</template>

В этом сценарии элемент невидим, но всегда существует в коде. get() или find() и .exists() всегда будет находить элемент  – потому что элемент все еще находится в DOM .

isVisible()

Предоставляет возможность проверять наличие скрытых элементов. В частности, isVisible() будет применяться, если:

  • элемент или его предки display:none или имеют visibility: hidden или opacity :0
  • элемент или его предки расположены внутри свернутого <details> тега
  • элемент или его предки обладают hidden атрибутом

В любом из этих случаев isVisible() возвращается значение false.

Тестовые сценарии v-show будут выглядеть следующим образом:

import { mount } from '@vue/test-utils';
import { describe, it } from 'vitest';
import Nav from '@/components/Nav.vue';

describe('Nav.vue',()=>{
    it('visibility ', ()=>{
        const wrapper = mount(Nav);

        expect(wrapper.get('#user-dropdown').isVisible()).toBe(false);
    });
})

Заключение

  • Используйте find() вместе с exists() для проверки того, находится ли элемент в DOM.
  • Используйте  get() если вы ожидаете, что элемент будет находиться в DOM.
  • Используйте get() c isVisible() для проверки видимости элемента, находящегося в DOM.