Unit testing 测试redux连接组件

Unit testing 测试redux连接组件,unit-testing,redux,sinon,enzyme,jestjs,Unit Testing,Redux,Sinon,Enzyme,Jestjs,我在React Redux中有以下连接的组件 export class IncrementalSearch extends React.Component { constructor(props) { super(props); this.onSearch$ = new Subject(); this.onChange = this.onChange.bind(this); } componentDidMount() {

我在React Redux中有以下连接的组件

export class IncrementalSearch extends React.Component {

    constructor(props) {
        super(props);
        this.onSearch$ = new Subject();
        this.onChange = this.onChange.bind(this);
    }

    componentDidMount() {
        this.subscription = this.onSearch$
            .debounceTime(300)
            .subscribe(debounced => {
                this.props.onPerformIncrementalSearch(debounced);
            });
    }

    componentWillUnmount() {
        if (this.subscription) {
            this.subscription.unsubscribe();
        }
    }

    onChange(e) {
        const newText = e.target.value;
        this.onSearch$.next(newText);
    }

    render() {
        return (
            <div className={styles.srchBoxContaner}>
                <input
                    className={styles.incSrchTextBox}
                    type="text" name="search" id="searchInput" placeholder="Search.."
                    onChange={this.onChange}
                />
            </div>
        );
    }
}

const mapDispatchToProps = (dispatch) => ({
    onPerformIncrementalSearch: (searchText) => {
        dispatch(performIncrementalStoreSearch(searchText));
    }
});

const IncrementalSearchComponent = connect(null, mapDispatchToProps)(IncrementalSearch);
export default IncrementalSearchComponent;
导出类增量搜索扩展React.Component{
建造师(道具){
超级(道具);
this.onSearch$=新主题();
this.onChange=this.onChange.bind(this);
}
componentDidMount(){
this.subscription=this.onSearch$
.debounceTime(300)
.订阅(取消公告=>{
此.props.onPerformIncrementalSearch(取消公告);
});
}
组件将卸载(){
如果(此订阅){
this.subscription.unsubscripte();
}
}
onChange(e){
const newText=e.target.value;
this.onSearch$.next(newText);
}
render(){
返回(
);
}
}
const mapDispatchToProps=(调度)=>({
onPerformIncrementalSearch:(搜索文本)=>{
发送(执行增量存储搜索(搜索文本));
}
});
const IncrementalSearchComponent=connect(null,mapDispatchToProps)(IncrementalSearch);
导出默认增量搜索组件;
我现在正试图为连接的组件编写一个单元测试。我在用玩笑、酶和西农。到目前为止,这就是我的单元测试的样子

it('calls \'onPerformIncrementalSearch\' when the user types in something', () => {
    const mockStore = configureStore();

    const onPerformIncrementalSearchSpy = sinon.spy();
    const mapStateToProps = null;
    const mapDispatchToProps = {
        onPerformIncrementalSearch: onPerformIncrementalSearchSpy
    };

    const mappedProps = { mapStateToProps, mapDispatchToProps };

    const incrementalSearchWrapper =
        mount(
            <Provider store={mockStore}>
                <IncrementalSearchComponent
                    onPerformIncrementalSearch={onPerformIncrementalSearchSpy}
                    props={mappedProps}
                    store={mockStore}
                />
            </Provider>
        );


    //find the input element
    const searchInput = incrementalSearchWrapper.find('#searchInput');
    searchInput.node.value = 'David';
    searchInput.simulate('change', searchInput);
    expect(onPerformIncrementalSearchSpy.called).toEqual(true);
    // onChangeSpy.restore();
});
it('calls'onPerformIncrementalSearch\'当用户键入内容时,()=>{
const mockStore=configureStore();
const onPerformIncrementalSearchSpy=sinon.spy();
const mapStateToProps=null;
const mapDispatchToProps={
onPerformIncrementalSearch:onPerformIncrementalSearchSpy
};
const mappedProps={mapStateToProps,mapsDispatchToprops};
常量递增搜索包装器=
坐骑(
);
//查找输入元素
const searchInput=incrementalSearchWrapper.find(“#searchInput”);
searchInput.node.value='David';
searchInput.simulate('change',searchInput);
expect(onPerformIncrementalSearchSpy.called).toEqual(true);
//onChangeSpy.restore();
});
然而,当我运行这个测试时,我得到以下错误

TypeError:无法读取未定义的属性“bind”


如何解决此问题?

测试连接的组件可能是一件非常痛苦的事情。我发现,尝试用
提供商
包装您的组件,让它们能够访问存储区,这是一件非常麻烦的事情

相反,我只需要导出组件,
mapstatetops
mapsdispatchtoprops
并分别测试它们。如果您将连接的组件导出为默认组件,则应用程序仍将正常工作

丹·阿布拉莫夫(Redux的合著者)在一篇文章中提出了这种方法


在测试连接的组件时,我还建议查看而不是使用
mount

测试连接的组件可能是一个巨大的痛苦。我发现,尝试用
提供商
包装您的组件,让它们能够访问存储区,这是一件非常麻烦的事情

相反,我只需要导出组件,
mapstatetops
mapsdispatchtoprops
并分别测试它们。如果您将连接的组件导出为默认组件,则应用程序仍将正常工作

丹·阿布拉莫夫(Redux的合著者)在一篇文章中提出了这种方法


在测试连接的组件时,我还建议查看而不是使用
mount

但是连接的组件不仅仅是MapStateTrops和mapDispatchToProps,我还需要测试组件中的其他逻辑。因此,如何测试它?您仍然可以通过这种方法测试组件中的逻辑。您只需要两个
导出
。一种是导出连接的组件
export default connect…
,您可以通过
import{default as myComponent}
在应用程序中导入该组件。您还可以像导出类myComponent那样导出未连接的组件,并像导入类myComponent那样在测试中导入。然后,您可以测试组件中的所有逻辑,而不必担心访问存储和测试连接的组件。可能有助于进一步解释。可能我不理解一些东西,我已经导出了连接和未连接的组件,当我只是尝试装载或浅化连接的组件以测试其逻辑时,问题就出现了。有一个我可以使用的工作示例吗?比尔的观点是,您不需要测试
connect
函数,因为这不是您的代码。您的代码都在未连接组件和
mapState/DispatchToProps
中。如果您测试了这些,那么您已经测试了所有逻辑。但是连接的组件不仅仅是mapStateToprops和mapDispatchToProps,我还需要测试组件中的其他逻辑。因此,如何测试它?您仍然可以通过这种方法测试组件中的逻辑。您只需要两个
导出
。一种是导出连接的组件
export default connect…
,您可以通过
import{default as myComponent}
在应用程序中导入该组件。您还可以像导出类myComponent那样导出未连接的组件,并像导入类myComponent那样在测试中导入。然后,您可以测试组件中的所有逻辑,而不必担心访问存储和测试连接的组件。可能有助于进一步解释。可能我不理解一些东西,我已经导出了连接和未连接的组件,当我只是尝试装载或浅化连接的组件以测试其逻辑时,问题就出现了。有一个我可以使用的工作示例吗?比尔的观点是,您不需要测试
connect
函数,因为这不是您的代码。您的代码都在未连接的组件中,
mapState/DispatchToProps