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

База насмешек

Начнем с простых с функции, которую относительно легко протестировать:

function app = (fn) => {
  const a = fn()
  ...
  return ...
}

Чтобы протестировать app, мы можем сделать фиктивную замену fn, а затем передать ее в ваш app, как обычно:

test('app', () => {
  let mockedFn = jest.fn()
  app(mockedFn)
  
  expect(mockedFn).toHaveBeenCalled()
})

Описанный выше подход не только позволяет протестировать нашу функцию, но и обеспечивает исключительный уровень уверенности. Пока мы можем предоставить fn, мы можем контролировать надежность этого модуля, даже если это черный ящик без доступа к реализации. Обратите внимание, что наш уровень достоверности основан не на удаче, а на том, что все зависимости объявлены в интерфейсе. Именно по этой причине при разработке собственной функции вы должны стремиться к этому. цель, потому что это сделает вашу жизнь намного проще.

Когда тестирование становится сложным

К сожалению, мы не всегда можем требовать идеального дизайна интерфейса. В половине случаев, если не писать библиотеку с нуля, вы столкнетесь со случаем, когда написанная функция не несет этого неявного интерфейса. Давайте рассмотрим один пример:

import axios from 'axios'

function app() {
  const user = axios.get('qplot.com');
  if (!user) return null

  // now we can use this user
  return ...
}

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

Функция app не имеет входных параметров, т. е. явного интерфейса, однако у нее есть скрытая зависимость axios, которая не прописывается, а упоминается внутри. Размышляя над тем, что мы заявили в начале, если мы не сможем точно контролировать все зависимости, мы не обретем необходимой уверенности. Поэтому решение состоит в том, чтобы найти способ имитировать axios, чтобы мы могли контролировать его поведение в тестовой среде. Позвольте мне показать вам один быстрый пример издевательства над ним:

import axois from 'axois' 

jest.mock('axios', () => ({
  get: (url) => Promise.resolve('fang')
}))

test('app', () => {
  app()  
  // do rest of testing
})

Сначала мы импортируем axios и подтверждаем, что есть функция get, ответ которой мы хотим имитировать. Поэтому всякий раз, когда внутри app вызывается axios.get, он запускает нашу фиктивную версию, в этом конкретном тесте мы хотим установить user равным fang, не заходя в Интернет туда и обратно.

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

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

Вы можете задаться вопросом, почему мы вообще хотим иметь скрытые зависимости. Это более философский вопрос: если вы живете в мире, вы не можете жить в одиночестве, как бы вы ни старались, вы получите какие-то отношения, которые не очевидны на поверхности . Написание функции со всевозможными зависимостями работает аналогичным образом. Технически вы можете вызвать источник этих зависимостей из глобальных переменных, внешних библиотек или побочных эффектов. Как бы вы их ни понимали, они в общем-то не под нашим контролем.

💡 Управление зависимостями становится намного проще, если вы используете Bit. В Bit Workspace вам не нужно указывать npm, pnpm или yarn, какие зависимости компонентов необходимо установить, а также если это зависимость dev или prod. Bit динамически генерирует файлы package.json для каждого из них и может безболезненно с этим справиться. Узнайте больше об этом здесь и здесь.

Узнайте больше здесь:



Краткое содержание

Я показал вам способы имитации как явных, так и скрытых зависимостей. Поэтому, когда вы пишете тесты, сначала найдите их, а затем смоделируйте их, удачного кодирования ;)

Создавайте приложения с повторно используемыми компонентами, как Lego

Инструмент с открытым исходным кодом Bit помогает более чем 250 000 разработчиков создавать приложения с компонентами.

Превратите любой пользовательский интерфейс, функцию или страницу в компонент многократного использования — и поделитесь им со своими приложениями. Легче сотрудничать и строить быстрее.

Подробнее

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

Микро-интерфейсы

Система дизайна

Совместное использование кода и повторное использование

Монорепо

Узнать больше: