2017-06-16 36 views
1

我想测试我的组件中的Select组件正确调用我的onChangeonBlur处理程序。我使用jest作为我的测试框架,使用enzyme来渲染我的组件以进行测试。需要测试处理程序道具是由复合React组件调用的

组件

import {Select} from 'antd' 

function MyComponent (props) { 
    const { onChange, onBlur, value, ...rest} = props 
    return (<Select 
    {...rest} 
    value={value} 
    onChange={onChange} 
    onBlur={onBlur} 
    />) 
} 

测试

describe('MyComponent',() => { 
    it('calls the onChange if the value of select changes',() => { 
     const onChange = jest.fn() 
    const options = { 
     enumOptions: [ 
     { 
      label: 'Foo', 
      value: 'foo' 
     }, 
     { 
      label: 'Bar', 
      value: 'bar' 
     } 
     ] 
    } 

    const wrapper = mount(<MyComponent options={options} onChange={onChange} />) 
    const select = wrapper.find('select') 
    select.simulate('change') 

    expect(onChange).toHaveBeenCalled() 

    }) 
}) 

问题/疑问

的问题是,Select组件不渲染select的Elemen T,所以试图抓住select元素和simulate事件上它会导致一个问题:

Method “simulate” is only meant to be run on a single node. 0 found instead. 

    at ReactWrapper.single (node_modules/enzyme/build/ReactWrapper.js:1419:17) 
    at ReactWrapper.simulate (node_modules/enzyme/build/ReactWrapper.js:769:14) 
    at Object.it (src/form-schema/widgets/Select/index.spec.js:172:12) 
     at Promise (<anonymous>) 
    at Promise.resolve.then.el (node_modules/p-map/index.js:42:16) 
     at <anonymous> 
    at process._tickCallback (internal/process/next_tick.js:169:7) 

我怎样才能确保onChange事件在组件上呼吁,而不必simulate它。

替代方法上Select

  1. setProps给力的变化。

我想用enzyme我发现setPropsenzyme仅支持根组件上,当我试图做我的组件中的道具传递到嵌套组件:

错误

ShallowWrapper::setProps() can only be called on the root 

    at ShallowWrapper.setProps (node_modules/enzyme/build/ShallowWrapper.js:339:17) 
    at Object.it (src/form-schema/widgets/Select/index.spec.js:150:12) 
     at Promise (<anonymous>) 
    at Promise.resolve.then.el (node_modules/p-map/index.js:42:16) 
     at <anonymous> 
    at process._tickCallback (internal/process/next_tick.js:169:7) 
上顶层组分
  • setProps两次:
  • 传递一个value道具,通过另一value托下来后立即引起变化:

    const wrapper = shallow(<Select options={options} onChange={onChange} />) 
    const select = wrapper.find(AntdSelect) 
    wrapper.setProps({value: 'bar'}) 
    wrapper.setProps({value: 'foo'}) 
    

    错误

    expect(jest.fn()).toHaveBeenCalled() 
    
    Expected mock function to have been called. 
    
        at Object.it (src/form-schema/widgets/Select/index.spec.js:153:22) 
         at Promise (<anonymous>) 
        at Promise.resolve.then.el (node_modules/p-map/index.js:42:16) 
         at <anonymous> 
        at process._tickCallback (internal/process/next_tick.js:169:7) 
    

    回答

    1
    1. 我建议你写测试用例不同组件不同。目前,你正在为MyComponent做这件事。所以,不要在这个套件中编写Select组件的测试用例。为Select选择一个不同的套件。您可以使用酶的.instance()方法来生成该功能。

    2. 如果假设您要导入的Select组件来自第三方库,那么您必须检查该组件内的元素。为了模拟select,您可能必须先模拟keyDown事件,然后在该组件中找到'li'元素,然后在'li'中模拟点击。取决于您使用的库。

    3.在这里,你只是在嘲笑这个功能。你必须设置一个间谍为了测试该功能是否被调用。检查'sinon'。它与酶一起使用。

    describe('Select',() => { 
        it('calls the onChange if the value of select changes',() => { 
        const onChange = jest.fn(); 
        onChange= sinon.spy(); 
        const wrapper = mount(<Select options={options} onChange={onChange} 
        />) 
        wrapper.simulate('change') 
        expect(onChange.called).toEqual(true); 
         }); 
         }) 
    
    
    
        describe('MyComponent',() => { 
        it('check select component exists',() => { 
         const onChange = jest.fn() 
         const options = { 
         enumOptions: [ 
         { 
          label: 'Foo', 
          value: 'foo' 
         }, 
         { 
          label: 'Bar', 
          value: 'bar' 
         } 
         ] 
        } 
    
        const wrapper = mount(<MyComponent options={options} onChange= 
        {onChange} />) 
        const select = wrapper.find('select') 
        select.length.toEqual('1'); 
    
        }); 
        }) 
    

    这是如果您没有使用第三方库中的Select组件。

    相关问题