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

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

В этом посте мы узнаем, как настроить среду тестирования Jest в вашем проекте Node.js, а также приведем несколько примеров тестовых случаев.

Шаг 1. Настройте среду Jest.

1. Установите jest как зависимость для разработчиков, потому что нам не нужна jest в производственной среде. Нам нужен супертест для тестирования нашего HTTP-сервера Node.js.

npm i --save-dev jest supertest
Or 
yarn add --dev jest supertest

2. Вы всегда можете настроить jest в файле package.json, но рекомендуется создать файл jest.config.js для всех конфигураций, требуемых jest.

module.exports = {
 clearMocks: true,
 collectCoverage: true,
 coverageDirectory: 'coverage',
 coveragePathIgnorePatterns: [
  '/node_modules/',
  '/tests/',
  '/views/'
  '/keys/',
  '/public/',
  '/models/',
 ],
 globalSetup: './tests/setup.js',
 globalTeardown: './tests/teardown.js'
 setupFiles: [
  './tests/globalmocks.js',
 ],
 testEnvironment: 'node',
}

В приведенном выше файле мы перечислили некоторые свойства конфигурации, например:

i. clearMocks используется для указания, следует ли автоматически очищать фиктивные вызовы и экземпляры между каждым тестом.

ii. Собирать покрытие указывает, следует ли собирать информацию о покрытии при выполнении теста.

iii. Каталог покрытия указывает каталог, в который Jest должен выводить файлы покрытия.

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

v. global setup указывает путь к модулю, который экспортирует асинхронную функцию, которая запускается один раз перед всеми наборами тестов.

vi. globalTeardown указывает путь к модулю, который экспортирует асинхронную функцию, которая запускается один раз после всех наборов тестов.

vii. В установочных файлах указывается путь для настройки среды тестирования перед каждым тестом.

viii. test environment определяет среду тестирования.
Для получения подробных объяснений по каждому свойству конфигурации посетите здесь.

3. Теперь создайте папку тестов в корневом каталоге проекта. Эта папка будет содержать все файлы, относящиеся к вашим тестовым случаям.

а. Создайте файл setup.js для инициализации подключения к базе данных. Вы можете заполнить свою тестовую базу данных для настройки инициализированными данными.

const path = require('path')
const dotenv = require('dotenv')
dotenv.config({
 path: path.join(__dirname, '..', 'test.env'),
})
const models = require('../models')
module.exports = () => {
 return models.sequelize.authenticate()
 .then(()=> {
   return models.sequelize.query('SET FOREIGN_KEY_CHECKS = 0')
 })
 .then(() => {
   return models.sequelize.sync({
    force: true,
  })
 })
.then(()=> {
  return models.sequelize.query('SET FOREIGN_KEY_CHECKS = 1')
 }).then(() => {
   //seed you DB here
 })
}
module.exports.models = models

б. Создайте файл teardown.js, чтобы закрыть соединение с базой данных.

const path = require('path')
const dotenv = require('dotenv')
dotenv.config({
 path: path.join(__dirname, '..', 'test.env'),
})
const models = require('../models')
module.exports = async function () {
 await models.sequelize.close()
};

c. Создайте файл globalmock.js, чтобы имитировать сторонние сервисные функции. Использование сторонних сервисов и библиотек - обычная часть современных проектов. Сложно контролировать поведение сторонних сервисов, и для решения этой проблемы мы имитируем сторонний сервис. Мокинг просто позволяет вам заменить фактическую реализацию поддельным / фиксированным набором желаемого результата. Позже в этом посте мы будем издеваться над некоторыми функциями.

4. Давайте создадим папку Routes внутри папки Tests, чтобы протестировать все файлы маршрутизации. Все тестовые примеры должны иметь расширение «test.js» или «spec.js». Через который шутка идентифицирует тестовые файлы.

а. Создайте файл index.test.js, чтобы записать все тестовые примеры файлов index.js.

const request = require('supertest')
const app = require('../../app')
const client = request(app)
describe('index', () => {
 it('should show 200', async () => {
  const res = await client.get('/')
  expect(res.status).toBe(200)
 })
})

В приведенном выше коде мы импортировали супертест, который позволит нам создать тестовый HTTP-сервер node.js для тестирования всего CRUD API. Инициализируйте свой смоделированный сервер приложений.

я. «Описать» создает блок, который группирует связанные тестовые примеры вместе. Это используется для группировки всех тестовых примеров, связанных с одним API, как и все положительные и отрицательные тестовые примеры вместе. Это совершенно необязательно, вы можете тестировать функции самостоятельно.

II. Функция «Оно» выполняет собственное тестирование API. Вы также можете использовать «test» вместо него, оба они одинаковы. В качестве аргумента принимает имя функции, реализацию функции.

iii. Ожидать указывает, что ожидать в результате прохождения тестового примера. например. код статуса ответа должен быть 200. Доступны разные способы, вы можете прочитать их здесь.

5. Напишем полный набор тестовых примеров для API обновления аккаунта.

const request = require('supertest')
const app = require('../../app')
const client = request(app)
const urlPrefix = '/user'
describe('update User account Info', () => {
 it('should update user account info', async () => {
   const res = await client.put(`${urlPrefix}/account_info`)
    .set({
      authorization: token,
      Accept: 'json',
     })
    .send({
      uId: 2,
      emailId: "[email protected]",
      firstName: "John",
      lastName: "Doe",
      birthDate: "1996-02-02",
      height: 5.10Ft,
      weight: 80Kg,
      phoneNo: "+91-7777777777",
      metaData: {},
     })
    expect(res.status).not.toEqual(200)
  })
it('should not update user info without id', async () => {
  const res = await client.put(`${urlPrefix}/account_info`)
    .set({
      authorization: token,
      Accept: 'json',
     })
    .send({
      emailId: "[email protected]",
      firstName: "John",
      lastName: "Doe",
      birthDate: "1996-02-02",
      height: 5.10Ft,
      weight: 80Kg,
      phoneNo: "+91-7777777777",
      metaData: {},
     })
    expect(res.status).not.toEqual(200)
  })
it('should not update user info with wrong id', async () => {
  const res = await client.put(`${urlPrefix}/account_info`)
    .set({
      authorization: token,
      Accept: 'json',
     })
    .send({
      uId: 2000,
      emailId: "[email protected]",
      firstName: "John",
      lastName: "Doe",
      birthDate: "1996-02-02",
      height: 5.10Ft,
      weight: 80Kg,
      phoneNo: "+91-7777777777",
      metaData: {},
     })
    expect(res.status).not.toEqual(200)
  })
})

Вы можете выполнять все HTTP-вызовы, такие как get, post, put, delete и т. Д. Вы можете установить заголовок, используя метод «Set». Передайте данные как параметр тела, используя метод «Отправить».

// Mock Send email feature
jest.mock('../email-helper.js')
const emailHelper = require('../email-helper')
emailHelper.sendEmail.mockImplementation((fromEmail, toEmail, substitutions) => {
 if (emailHelper.fromEmail && emailHelper.toEmail) {
   return Promise.resolve({
    status: 200
   })
 } else {
   return Promise.reject(new Error("Email template dosen't exist"))
 }
});

В приведенном выше коде мы смоделировали функцию отправки электронной почты, которая отправляет электронное письмо пользователю с помощью nodemailer. Вы можете просто имитировать функцию и разрешить ее как переданную с кодом состояния 200. Вы можете имитировать все функции, результат которых ожидается. Напишите все имитируемые функции в созданном ранее файле globalmock.js.

6. Для запуска тестовых примеров используйте:

npx jest

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

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

Спасибо за внимание.

Больше контента на plainenglish.io