Используется в JSON или нет при тестировании снимков с Jest - PullRequest
0 голосов
/ 18 апреля 2020

Я новичок в React и тестирую свои компоненты. При реализации моментального тестирования я обнаружил следующие два подхода:

Подход 1

import React from 'react'
import renderer from 'react-test-renderer'
import Projects from './Projects'

it('renders Projects component properly', () => {
  const tree = renderer.create(<Projects />)
  expect(tree).toMatchSnapshot()
})

Подход 2

import React from 'react'
import renderer from 'react-test-renderer'
import Projects from './Projects'

it('renders Projects component properly', () => {
  const component = renderer.create(<Projects />)
  const tree = component.toJSON()
  expect(tree).toMatchSnapshot()
})

Важно ли вызывать toJSON в компоненте (подход 2) или вы можете просто передать его непосредственно для проверки toMatchSnapshot (подход 1)? Может кто-нибудь объяснить мне разницу между обоими подходами с точки зрения производительности?

1 Ответ

1 голос
/ 18 апреля 2020

TL; DR

При использовании toMatchSnapshot сопоставление toJSON вызывается для объекта, переданного в expect. Это часть некоторой цепочки проверок, которая может оказать незначительное, в подавляющем большинстве реальных случаев, влияние на производительность. Я бы предложил назвать toJSON просто для следования принципу «явный лучше, чем неявный», и тот факт, что внутреннее поведение может быть изменено.

Объяснение

matcher использует SnapshotStates match метод , который сериализует объект. serialize просто вызывает pretty-format с набором плагинов.

Это точка входа в pretty-format , я добавил туда комментарии:

function prettyFormat(
  val: unknown,
  options?: PrettyFormat.OptionsReceived,
): string {
  if (options) {
    validateOptions(options);
    if (options.plugins) {
      const plugin = findPlugin(options.plugins, val);
      /* When val is a result of `toJSON` call 
         it has a $$typeof: Symbol.for('react.test.json') field so  
         it is handled by ReactTestComponent plugin in this point */
      if (plugin !== null) {
        return printPlugin(plugin, val, getConfig(options), '', 0, []);
      }
    }
  }

  // When `toJSON` is not called `printBasicValue` is invoked but is it pointless
  const basicResult = printBasicValue(
    val,
    getPrintFunctionName(options),
    getEscapeRegex(options),
    getEscapeString(options),
  );
  if (basicResult !== null) {
    return basicResult;
  }

  return printComplexValue(val, getConfig(options), '', 0, []);
}

printBasicValue просто выполняет набор проверок, все они терпят неудачу для объекта, поэтому printComplexValue вступает в свою очередь. Вот фрагмент, где вызывается .toJSON().

  if (
    config.callToJSON &&
    !hitMaxDepth &&
    val.toJSON &&
    typeof val.toJSON === 'function' &&
    !hasCalledToJSON
  ) {
    return printer(val.toJSON(), config, indentation, depth, refs, true);
  }

printer находит плагин и вызывает его в самом начале, так что это не имеет значения.

  const plugin = findPlugin(config.plugins, val);
  if (plugin !== null) {
    return printPlugin(plugin, val, config, indentation, depth, refs);
  }

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...