Skip to content

Latest commit

 

History

History
72 lines (55 loc) · 3.74 KB

testing-with-mocks.md

File metadata and controls

72 lines (55 loc) · 3.74 KB

Тестирование с моками

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

Для этого в модульных тестах используется понятие "мок" ("mock") – это объект, за вызовами методов которого мы можем следить и даже управлять их результатами. Чтобы не тестировать и компонент, и его зависимость в связке, нам достаточно внедрить вместо зависимости созданный мок-объект.

vue-loader предоставляет возможность внедрять произвольные зависимости в *.vue компоненты, используя inject-loader. Основная идея состоит в том, что вместо прямой подгрузки модуля компонента мы используем inject-loader, чтобы создать "фабричную функцию" для этого модуля. Когда мы вызовем эту функцию с мок-объектом, она вернет нам экземпляр модуля с внедренными мок-объектами.

Допустим, у нас есть следующий компонент:

<!-- example.vue -->
<template>
  <div class="msg">{{ msg }}</div>
</template>

<script>
// эту зависимость нужно подменить мок-объектом
import SomeService from '../service'

export default {
  data () {
    return {
      msg: SomeService.msg
    }
  }
}
</script>

Вот как получить его с мок-объектами:

Заметка: [email protected] еще не в стабильной версии

npm install inject-loader@^2.0.0 --save-dev
// example.spec.js
const ExampleInjector = require('!!vue-loader?inject!./example.vue')

Обратите внимание на эту безумную строку импорта – мы используем запросы к webpack загрузчику. Краткое пояснение:

  • !! в начале строки означает "отключи все загрузчики из глобальной конфигурации"
  • vue-loader?inject! значит "используй загрузчик vue-loader и передай запрос ?inject". Это заставляет vue-loader скомпилировать компонент в режиме внедрения зависимостей.

Полученный ExampleInjector – это фабричная функция, которую можно вызвать, чтобы создать экземпляр модуля example.vue:

const ExampleWithMocks = ExampleInjector({
  // mock it
  '../service': {
    msg: 'Привет от мок-сервиса!'
  }
})

Наконец, мы можем тестировать компонент как обычно:

it('should render', () => {
  const vm = new Vue({
    template: '<div><test></test></div>',
    components: {
      'test': ExampleWithMocks
    }
  }).$mount()
  expect(vm.$el.querySelector('.msg').textContent).toBe('Привет от мок-сервиса!')
})