代码之家  ›  专栏  ›  技术社区  ›  StefanN

this.props不是函数(浅层渲染)

  •  -1
  • StefanN  · 技术社区  · 6 年前

    我在用jest/enzyme测试我的(遗留)组件时遇到了问题。 它看起来像这样:

    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 回复  |  直到 6 年前
        1
  •  3
  •   mars328    6 年前

    看起来您正在进行单元测试而不是集成测试。

    通常,您应该使用模拟函数测试组件以获得最佳实践,而不是使用道具中的实际方法。您还可以在不同的定义位置测试props函数。

    因此,从您的上下文中,您可以使用jest.fn()模拟handleSelect,并在更新下拉值时测试它是否被调用。

       let wrapper = shallow(<MyComponent/>);
       wrapper.instance().handleSelect = jest.fn();
       .....
       expect(wrapper.instance().handleSelect).toHaveBeenCalled();
    
    
        2
  •  0
  •   arnaudambro    6 年前

    这不是测试中的问题,而是组件中的问题。错误最有可能发生在 this.props[ name ]( value ); ,我不认为这是你想做的 this.props.save(value) 看起来更加连贯。

        3
  •  0
  •   iamaatoh    6 年前

    将此添加到构造函数中:

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

    由于它没有绑定,我认为它没有访问权限 this.props 从组件。

    在调用它之前,您还应该尝试检查它是否是一个已定义的函数 handleSelect