【问题标题】:Pass jest.fn() function to mapDispatchToProps in enzyme shallow render将 jest.fn() 函数传递给酶浅渲染中的 mapDispatchToProps
【发布时间】:2018-12-02 01:05:35
【问题描述】:

有非常简单的组件:

从“prop-types”导入 PropTypes 从“反应”导入反应 从'react-redux'导入{连接}

class MyComponent extends React.Component {
  componentWillMount() {
    if (this.props.shouldDoSth) {
      this.props.doSth()
    }
  }

  render () {
    return null
  }
}

MyComponent.propTypes = {
  doSth: PropTypes.func.isRequired,
  shouldDoSth: PropTypes.bool.isRequired
}

const mapStateToProps = (state) => {
  return {
    shouldDoSth: state.shouldDoSth,
  }
}

const mapDispatchToProps = (dispatch) => ({
  doSth: () => console.log('you should not see me')
})

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)

我想测试当shouldDoSth 等于true 时是否调用doSth

我写了一个测试:

describe('call doSth when shouldDoSth', () => {
  it('calls doSth', () => {
    const doSthMock = jest.fn()
    const store = mockStore({shouldDoSth: true})
    shallow(<MyComponent doSth={doSthMock}/>, { context: { store } }).dive()
    expect(doSthMock).toHaveBeenCalled()
  })
})

但似乎虽然我将 doSth 作为道具传递,但在执行 console.log('im not a mock') 时,它会被 mapDispatchToProps 覆盖。

如何正确传递/覆盖/分配doSth 函数以使组件使用模拟而不是mapDispatchToProps 中的函数。或者,也许我正在做一些根本不应该被允许的事情,并且有“正确”的方式来测试我的案例。我应该只模拟调度并检查它是否使用正确的参数调用?

【问题讨论】:

    标签: javascript redux jestjs enzyme redux-mock-store


    【解决方案1】:

    我认为你需要弄清楚的一件事是你是否希望 doSth 成为一个道具,或者一个连接在 mapDispatchToProps 中的 redux 操作。

    如果它是一个道具,那么您可以将它连接到父级(容器)中的 redux。从该组件的 mapDispatchToProps 中删除它。这将使组件更具可测试性。

    如果你希望它是一个连接在这个组件中的redux action,那么将这个action移出这个组件是有意义的,比如actions.js,将它导入到这个组件中,然后在测试中模拟它jest.mock('actions.js', () =&gt; ({doSth: jest.mock()}))

    【讨论】:

      【解决方案2】:

      导出未连接的组件并在测试中使用它,您将能够覆盖 mapDispatchToProps 操作。

      export class MyComponent extends React.Component {
        componentWillMount() {
          if (this.props.shouldDoSth) {
            this.props.doSth()
          }
        }
      
        render () {
          return null
        }
      }
      
      MyComponent.propTypes = {
        doSth: PropTypes.func.isRequired,
        shouldDoSth: PropTypes.bool.isRequired
      }
      
      const mapStateToProps = (state) => {
        return {
          shouldDoSth: state.shouldDoSth,
        }
      }
      
      const mapDispatchToProps = (dispatch) => ({
        doSth: () => console.log('you should not see me')
      })
      
      export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)
      
      
      
      
      import {MyComponent} from '../MyComponent'
      describe('call doSth when shouldDoSth', () => {
        it('calls doSth', () => {
          const doSthMock = jest.fn()
          const store = mockStore({shouldDoSth: true})
          shallow(<MyComponent doSth={doSthMock}/>, { context: { store } }).dive()
          expect(doSthMock).toHaveBeenCalled()
        })
      })
      

      【讨论】:

        【解决方案3】:

        我认为你应该问问自己是要测试未连接的 MyComponent 还是连接的。

        这里有两个讨论可能对您有所帮助:Am I testing connected components correclty?Can't reference containers wrapped in a Provider or by connect with Enzyme

        如果您没有正确测试动作或状态,您可能会忘记 mapStateToProps 和 mapDispatchToProps(这些进程已经被 redux 测试过)并通过 props 传递值。

        检查以下示例:

        describe('MyComponent', () => {
        
        let wrapper;
        
        const doSthMock = jest.fn();
        
        beforeEach(() => {
        
            const componentProps = {
                doSth: true,
            };
        
            wrapper = mount(
                    <MyComponent
                        {... componentProps}
                        doSth={doSthMock}
                    />
            );
        
        });
        
        it('+++ render the component', () => {
            expect(wrapper.length).toEqual(1);
        });
        
        it('+++ call doSth when shouldDoSth', () => {
            expect(doSthMock).toHaveBeenCalled();
        });
        

        })

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-11-18
          • 2018-09-25
          • 1970-01-01
          • 2018-04-03
          • 2020-08-26
          • 1970-01-01
          • 2017-10-20
          • 1970-01-01
          相关资源
          最近更新 更多