this.props не является функцией (неглубокий рендеринг) - PullRequest
0 голосов
/ 19 июня 2020

У меня проблемы с тестированием моего (устаревшего) компонента с помощью jest / энзима. Это выглядит так:

export default class MyComponent extends Component {
    constructor( props ) {
        super( props );
        this.handleSelect = this.handleSelect.bind( this );
    }

    handleSelect( event ) {
        const { name, value } = event.target;
        this.props[ name ]( value );
    }

    render() {
        return (
            <label>
                Dropdown 1{ ' ' }
                <select
                    name="dropdown1"
                    value={ status }
                    data-testid="dropdown-1"
                    onChange={ this.handleSelect }
                >
                    <option value="">Any</option>
                    <option value="item1">Item 1</option>
                    <option value="item2">Item 2</option>
                    <option value="item3">Item 3</option>
                </select>
            </label>
        );
    }
}

Методы передаются как реквизиты! В этом случае при изменении значения будет вызываться handleSelect и вызывается this.props['dropdown1'](value).

И мой тест выглядит так:

import React from 'react';
import { shallow } from 'enzyme';

test( 'select an item from the dropdown', () => {
    const status = wrapper.find( 'select[data-testid="dropdown-1"]' );
    status.simulate( 'change', { target: { value: 'item1' } } );
    expect(status.prop('value')).toEqual('item1');
} );

Он отображает следующую ошибку:

TypeError: this.props[name] is not a function

Зависимости в package.json:

"devDependencies": {
    ...
    "enzyme-to-json": "^3.4.0",
    "jest": "^24.9.0",
    "react": "^16.9.0",
    "react-dom": "^16.9.0",

Кто-нибудь может мне с этим помочь?

Ответы [ 3 ]

3 голосов
/ 19 июня 2020

Похоже, что вы проводите модульный тест вместо интеграционного.

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

поэтому из вашего контекста вы можете имитировать handleSelect с помощью jest.fn () и просто проверить, вызывается ли он при обновлении значения раскрывающегося списка .

   let wrapper = shallow(<MyComponent/>);
   wrapper.instance().handleSelect = jest.fn();
   .....
   expect(wrapper.instance().handleSelect).toHaveBeenCalled();

0 голосов
/ 19 июня 2020

Добавьте это в свой конструктор:

this.handleSelect = this.handleSelect.bind( this );

Поскольку он не привязан, я думаю, что у него нет доступа this.props из компонента.

Вам также следует попробовать проверить если это определенная функция перед ее вызовом в handleSelect

0 голосов
/ 19 июня 2020

Это проблема не в вашем тесте, а в вашем компоненте. Ошибка, скорее всего, в this.props[ name ]( value );, я не думаю, что это то, что вы хотите делать. Sometinh вроде this.props.save(value) выглядит более связным.

...