Как проверить реакцию Проптипов через Jest?

Я пишу тесты Jest для моего кода React и надеюсь использовать / проверить проверки PropType. Я совершенно Новичок во Вселенной Javascript. Я использую npm для установки react-0.11.2 и просто:

var React = require('react/addons');

в моих тестах. Мой тест очень похож на пример учебника jest/react с кодом, таким как:

var eventCell = TestUtils.renderIntoDocument(
  <EventCell
    slot={slot}
    weekId={weekId}
    day={day}
    eventTypes={eventTypes}
    />
);

var time = TestUtils.findRenderedDOMComponentWithClass(eventCell, 'time');
expect(time.getDOMNode().textContent).toEqual('19:00 ');

однако кажется, что PropType проверяет в EventCell компонент не срабатывает. Я понимаю, что проверки выполняются только в разработке режим, но тогда я также думал, что получение react через npm дал вам версию разработки. Проверки запускаются в моем браузере, когда я создаю компонент с watchify.

что я упустил?

5 ответов


основная проблема-это Как проверить console.log?

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

вот пример реализации с использованием Синон.js (Синон.js предоставляет автономные шпионы, заглушки и насмешки):

import {
    expect
} from 'chai';
import DateName from './../../src/app/components/DateName';
import createComponent from './create-component';
import sinon from 'sinon';

describe('DateName', () => {
    it('throws an error if date input does not represent 12:00:00 AM UTC', () => {
        let stub;

        stub = sinon.stub(console, 'error');

        createComponent(DateName, {date: 1470009600000});

        expect(stub.calledOnce).to.equal(true);
        expect(stub.calledWithExactly('Warning: Failed propType: Date unix timestamp must represent 00:00:00 (HH:mm:ss) time.')).to.equal(true);

        console.error.restore();
    });
});

In этот пример DataName компонент выдаст ошибку при инициализации со значением метки времени, которое не представляет точную дату (12:00:00 AM).

я тушу console.error метод (это то, что Facebook warning модуль использует внутренне для генерации ошибки). Я гарантирую, что заглушка была вызвана один раз и с точно одним параметром, представляющим ошибку.


интро

ответ @Gajus определенно помог мне (так,спасибо Gajus). Тем не менее, я думал, что дам ответ, который:

  • использует вверх-к-дата реагируют (программы V15.4.1)
  • использует шутка (который поставляется с React)
  • позволяет проводить испытания несколько значений prop для одной опоры
  • Is больше generic

резюме

как подход, предложенный здесь Gajus и других остальных, основной подход я предлагаю и определить, является ли или нет console.error используется React в ответ на неприемлемое значение тестовой опоры. В частности, этот подход предполагает выполнение следующих действий для каждого значения тестовой опоры:

  • издевательство и очистка console.error (для обеспечения предварительного звонки в console.error не вмешиваясь),
  • создание компонента с помощью тестового значения prop и
  • подтверждение ли или нет console.error была уволена как и ожидалось.

на testPropTypes функции

следующий код можно поместить или внутри теста или как отдельный импортированный / необходимый модуль / файл:

const testPropTypes = (component, propName, arraysOfTestValues, otherProps) => {
    console.error = jest.fn();
    const _test = (testValues, expectError) => {
        for (let propValue of testValues) {
            console.error.mockClear();
            React.createElement(component, {...otherProps, [propName]: propValue});
            expect(console.error).toHaveBeenCalledTimes(expectError ? 1 : 0);
        }
    };
    _test(arraysOfTestValues[0], false);
    _test(arraysOfTestValues[1], true);
};

вызов Функция

любой тест, исследовав propTypes can вызов testPropTypes через три или четыре параметры:

  • component, реагировать компонент это модифицируется опорой;
  • propName строка название реквизита при тестировании;
  • arraysOfTestValues, массив массивов все необходимые тестовые значения упорки, котор нужно испытать:
    • в первый суб-массив содержит все приемлемо проверить значения опоры, в то время как
    • второй под-массив содержит все недопустимо проверить значения опоры; и
  • дополнительно otherProps, объект, содержащий prop пары имя / значение для любых других необходимых реквизита этого компонента.

    на otherProps объект необходим, чтобы гарантировать, что React не делает нерелевантные вызовы console.error потому что других необходимых реквизит случайно отсутствует. Просто включите одно допустимое значение для любых необходимых реквизитов, например {requiredPropName1: anyAcceptableValue, requiredPropName2: anyAcceptableValue}.

Логическая Функция

функция делает следующее:

  • это устанавливает над console.error что React использует для отчета реквизитов неправильного типа.

  • на в каждом суб-массиве тест проп значения это петли через каждый тест проп значение в каждом суб-массиве для проверки типа prop:

    • первый из двух суб-массивов должен быть списком приемлемые значения опоры теста.
    • второй должен быть недопустимые значения тестовых опор.
  • в пределах цикла для каждого отдельного значения опоры теста,the console.error макет сначала очистили так что любые сообщения об ошибках можно предположить, что обнаружен в результате этого теста.

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

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

тестирование на необязательный и требуемый реквизит

обратите внимание, что назначение null (или undefined) для значения опоры, с точки зрения React, по существу то же самое, что не предоставлять никакого значения для этой опоры. По определению это приемлемо для факультативной опоры, но неприемлемо для требуемой. Таким образом, поместив null в массиве приемлемых или неприемлемых значений вы проверяете, является ли эта опора необязательно или требуется соответственно.

Пример Кода

компонент MyComponent.js (просто propTypes):

MyComponent.propTypes = {
    myProp1: React.PropTypes.number,      // optional number
    myProp2: React.PropTypes.oneOfType([  // required number or array of numbers
        React.PropTypes.number,
        React.PropTypes.arrayOf(React.PropTypes.number)
    ]).isRequired

компонент MyComponent.тест.js:

describe('MyComponent', () => {

    it('should accept an optional number for myProp1', () => {
        const testValues = [
            [0, null],   // acceptable values; note: null is acceptable
            ['', []] // unacceptable values
        ];
        testPropTypes(MyComponent, 'myProp1', testValues, {myProp2: 123});
    });

    it('should require a number or an array of numbers for myProp2', () => {
        const testValues = [
            [0, [0]], // acceptable values
            ['', null] // unacceptable values; note: null is unacceptable
        ];
        testPropTypes(MyComponent, 'myProp2', testValues);
    });
});

ограничение этого подхода (важно)

в настоящее время существуют некоторые существенные ограничения на то, как вы можете использовать этот подход, который, если перешагнуть, может быть источником некоторых труднодоступных проверка ошибок. Причины и последствия этих ограничений объясняются в это другой так Вопрос / ответ. В общем, для простых типов prop, таких как for myProp1, вы можете проверить столько неприемлемых не -null test prop значения, как вы хотите пока они все разные типы данных. Для некоторых сложных типов опор, например для myProp2, вы можете проверить только один недопустимо номера-null проп стоимостью любой тип. См. этот другой вопрос / ответ для более углубленного обсуждения.


издевательский console.error не подходит для использования в модульных тестах! @AndrewWillems, связанный с еще один вопрос в комментарии выше описаны проблемы с этим подходом.

проверить этот вопрос на facebook / prop-types для обсуждения возможности этой библиотеки выбрасывать вместо регистрации ошибок propType (на момент написания статьи она не поддерживается).

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

import PropTypes from 'prop-types';
import checkPropTypes from 'check-prop-types';

const HelloComponent = ({ name }) => (
  <h1>Hi, {name}</h1>
);

HelloComponent.propTypes = {
  name: PropTypes.string.isRequired,
};

let result = checkPropTypes(HelloComponent.propTypes, { name: 'Julia' }, 'prop', HelloComponent.name);
assert(`result` === null);

result = checkPropTypes(HelloComponent.propTypes, { name: 123 }, 'prop', HelloComponent.name);
assert(`result` === 'Failed prop type: Invalid prop `name` of type `number` supplied to `HelloComponent`, expected `string`.');

новый пакет jest-prop-тип-ошибка просто добавить и не на PropType ошибки:

установить с помощью:

yarn add -D jest-prop-type-error

затем добавьте следующий код package.json ' s setupFiles на :

"setupFiles": [
  "jest-prop-type-error"
]

поскольку ReactJS будет отправлять предупреждения только на консоль, но на самом деле не будет выдавать ошибку, я тестирую значения prop следующим образом:

var myTestElement = TestUtils.renderIntoDocument(
<MyTestElement height={100} /> );

it("check MyTestElement props", function() {

   expect( typeof myTestElement.props.height ).toEqual ( 'number' );

});