Jest Unit Test не может определить видимость компонентов Vuetify

У меня есть проект Vue2 с Vuetify, и я использую Jest для модульного тестирования своего кода. Я начинаю тестировать образец кода, и я просто не могу заставить Jest определить, является ли Vuetifyv-alertкомпонент виден или нет. Я пробовал встроенные методы Jest, а также добавлял Jest-dom и использовалtoBeVisible() метод, и пока ничего не работает.

Если вы посмотрите на компонент Test.vue, то v-alert компонент по умолчанию скрыт (его стиль установлен на display: none;)

Модульный тест говорит expect(alert).not.toBeVisible() который должен пройти, но он всегда терпит неудачу, независимо от того, что v-alertмодель установлена ​​на. Если я изменю тест наexpect(alert).toBeVisible() это проходит независимо от v-alert модель установлена ​​в значение true/false.

Если я изменю тест на expect(alert).toHaveStyle({ display: 'none' }); он не работает независимо от того, установлена ​​ли у меня модель в значение true/false.

Итак, насколько я могу судить, модульный тест Jest НЕ МОЖЕТ определить видимость v-alertкомпонент вообще. Эти же тесты отлично работают наv-btn компонент в порядке, так почему же v-alertперемена? Это всего лишь мой первый образец модульного теста, который я пытался запустить уже 2 дня. У меня есть целое приложение для написания тестов, и пока Jest не очень хорошо работает с Vuetify... есть предложения?

// Компонент Test.vue

<template>
  <div>
    <v-btn ref="btn" depressed tile @click="showAlert">Show Alert</v-btn>
    <v-alert
      v-model="showError"
      ref="error-msg"
      type="error"
      transition="scale-transition"
      width="410"
      tile
      dense
      dismissible
      @input="clearError"
    >
      {{ errorText }}
    </v-alert>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showError: false,
      errorText: ''
    };
  },
  methods: {
    showAlert() {
      this.errorText = 'Test Error message';
      this.showError = true;
    },
    clearError() {
      this.errorText = '';
    }
  }
};
</script>

// Тест Jest Unit

// Libraries
import Vue from 'vue';
import Vuetify from 'vuetify';

// Components
import Test from '@/components/Login/Test.vue';

// Utilities
import { createLocalVue, shallowMount } from '@vue/test-utils';

// Import Jest Dom test utils.
import '@testing-library/jest-dom';

const localVue = createLocalVue();

Vue.use(Vuetify);

describe('Test Page', () => {
  let vuetify;

  beforeEach(() => {
    vuetify = new Vuetify();
  });

  it('Check visibility of button', () => {
    const wrapper = shallowMount(Test, {
      localVue,
      vuetify
    });

    const btn = wrapper.findComponent({ ref: 'btn' }).element;

    expect(btn).toBeVisible();
  });

  it('Error Message hidden on page load', () => {
    const wrapper = shallowMount(Test, {
      localVue,
      vuetify
    });

    const alert = wrapper.findComponent({ ref: 'error-msg' }).element;

    expect(alert).not.toBeVisible();
  });
});

// Package.json

"dependencies": {
    "vue": "^2.6.11",
    "vue-click-outside": "^1.1.0",
    "vue-debounce": "^2.5.7",
    "vue-router": "^3.3.4",
    "vuetify": "^2.2.11",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@babel/plugin-transform-runtime": "^7.10.3",
    "@babel/polyfill": "^7.10.1",
    "@fortawesome/fontawesome-free": "^5.13.1",
    "@testing-library/jest-dom": "^5.10.1",
    "@vue/cli-plugin-babel": "^4.4.5",
    "@vue/cli-plugin-e2e-nightwatch": "^4.4.5",
    "@vue/cli-plugin-eslint": "^4.4.5",
    "@vue/cli-plugin-unit-jest": "^4.4.5",
    "@vue/cli-service": "^4.4.5",
    "@vue/eslint-config-prettier": "^4.0.1",
    "@vue/test-utils": "^1.0.3",
    "babel-eslint": "^10.0.3",
    "babel-jest": "^26.1.0",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^6.2.2",
    "node-sass": "^4.14.1",
    "sass": "^1.26.9",
    "sass-loader": "^8.0.2",
    "vue-cli-plugin-vuetify": "^2.0.6",
    "vue-template-compiler": "^2.6.11",
    "vuetify-loader": "^1.5.0"
  }

1 ответ

Я столкнулся с аналогичной проблемой, поэтому решил использовать exists от @vue/test-utils вместо.

Документы для exists: https://vue-test-utils.vuejs.org/api/wrapper/

Я тоже решил использовать v-if (вместо того v-model) на v-alert элемент, чтобы скрыть / показать компонент.

Похоже, если v-if получает значение false, компонент / элемент в документе заменяется на <!---->, который отлично подходит для проверки, скрыт или отображается ваш компонент / элемент.

Видеть v-ifспецификация теста: https://github.com/vuejs/vue/blob/52719ccab8fccffbdf497b96d3731dc86f04c1ce/test/unit/features/directives/if.spec.js


SFC

Шаблон:

<template>
  <v-container>
    <v-btn
      @click='showError()'
      ref="showErrorButton">
      Show Error
    </v-btn>
    <v-alert
      v-if="errorEncountered"
      ref="errorAlert"
      colored-border
      type="error"
      elevation="2"
      >
      Oops! Something went wrong!
    </v-alert>
  <v-container>
<template>

Javascript:

export default {
  methods: {
    showError() {
      this.errorEncountered = true;
    }
  }
  data() {
    return {
      errorEncountered: false,
    };
  },
};

Всякий раз, когда errorEncountered обновляется, компонент v-alert будет отображаться / скрываться в зависимости от того, является ли значение истинным / ложным.


Тесты

describe('Component', () => {
  let wrapper;

  beforeEach(() => {
    wrapper = mount(Component, {
      localVue,
      vuetify,
    });
  });

  describe('When component is mounted', () => {
    it('Then the default value for errorEncountered should be false', () => {
      expect(wrapper.vm.errorEncountered).toBeFalse();
    });
    
    it('Then the default state for the error alert should be hidden', async () => {
      const errorAlert = wrapper.find({ ref: 'errorAlert' });
      expect(errorAlert.exists()).toBeFalse();
    });

    describe('When an error is encountered', () => {
      it('Then errorEncountered should be set to true', async () => {
        const showErrorButton = wrapper.find({ ref: 'showErrorButton' });
        showErrorButton.trigger('click');
        await Vue.nextTick();
        expect(wrapper.vm.errorEncountered).toBeTrue();
      });

      it('Then error alert should be visible', async () => {
        const showErrorButton = wrapper.find({ ref: 'showErrorButton' });
        showErrorButton.trigger('click');
        await Vue.nextTick();
        const errorAlert = wrapper.find({ ref: 'errorAlert' });
        expect(errorAlert.exists()).toBeTrue();
      });
    });
  });
Другие вопросы по тегам