Javascript TypeError:this.props.myMaterials.fetch不是函数

Javascript TypeError:this.props.myMaterials.fetch不是函数,javascript,reactjs,jestjs,Javascript,Reactjs,Jestjs,我正在使用react-test-renderer进行jest单元测试。测试用例失败并显示此错误 “TypeError:this.props.myMaterials.fetch不是函数” 其中this.props.notes.fetch位于组件willmount中。是否有解决方案可以在不使用酶的情况下解决此问题 myComponent.jsx: class myComponent extends React.Component { constructor(props) {

我正在使用
react-test-renderer
进行jest单元测试。测试用例失败并显示此错误

“TypeError:this.props.myMaterials.fetch不是函数”

其中
this.props.notes.fetch
位于
组件willmount
中。是否有解决方案可以在不使用酶的情况下解决此问题

myComponent.jsx:

class myComponent extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          column: this.getColumns(),
          pageNotFound: false
        };
      }


      componentWillMount() {
        this.props.notes.fetch(this.props.courseId);
        window.addEventListener('resize', this.handleResizeEvent);
        this.handleError = EventBus.on(constants.NOTES_NOT_FOUND, () => {
          this.setState({ pageNotFound: true });
        });
      }

      componentDidMount() {
        window.addEventListener('resize', this.handleResizeEvent);
      }

      componentWillUnmount() {
        window.removeEventListener('resize', this.handleResizeEvent);
        this.handleError();
      }

      handleResizeEvent = () => {
        this.setState({ column: this.getColumns() });
      };

      getColumns = () => (window.innerWidth > (constants.NOTES_MAX_COLUMNS * constants.NOTES_WIDTH) ?
        constants.NOTES_MAX_COLUMNS :
        Math.floor(window.innerWidth / constants.NOTES_WIDTH))

      callback = (msg, data) => {
      }
      render() {
        const { notes, language } = this.props;
        if (this.state.pageNotFound) {
          return (<div className="emptyMessage"><span>Empty</span></div>);
        }
        if (notes.loading) {
          return (<Progress/>);
        }
        // To Refresh Child component will receive props
        const lists = [...notes.cards];
        return (
          <div className="notesContainer" >
            <NoteBook notesList={lists} callback={this.callback} coloums={this.state.column} />
          </div>
        );
      }
    }

myComponent.propTypes = {
  notes: PropTypes.object,
  courseId: PropTypes.string,
  language: PropTypes.shape(shapes.language)
};
export default withRouter(myComponent);
类myComponent扩展了React.Component{ 建造师(道具){ 超级(道具); 此.state={ column:this.getColumns(), pageNotFound:false }; } 组件willmount(){ this.props.notes.fetch(this.props.courseId); window.addEventListener('resize',this.handleResizeEvent); this.handleError=EventBus.on(找不到常量.NOTES,()=>{ this.setState({pageNotFound:true}); }); } componentDidMount(){ window.addEventListener('resize',this.handleResizeEvent); } 组件将卸载(){ window.removeEventListener('resize',this.handleResizeEvent); 这个.handleError(); } HandlerResizeEvent=()=>{ this.setState({column:this.getColumns()}); }; getColumns=()=>(window.innerWidth>(constants.NOTES\u MAX\u COLUMNS*constants.NOTES\u WIDTH)? 常量.NOTES\u MAX\u列: 数学地板(window.innerWidth/constants.NOTES\u WIDTH)) 回调=(消息,数据)=>{ } render(){ const{notes,language}=this.props; if(this.state.pageNotFound){ 返回(空); } 如果(注意:装载){ 返回(); } //刷新子组件将收到道具 const list=[…notes.cards]; 返回( ); } } myComponent.propTypes={ 注意:PropTypes.object, courseId:PropTypes.string, 语言:PropTypes.shape(shapes.language) }; 使用路由器导出默认值(myComponent); myComponent.test.jsx:

const tree = renderer.create(
<myComponent.WrappedComponent/>).toJSON();
expect(tree).toMatchSnapshot();
});
const tree=renderer.create(
).toJSON();
expect(tree.toMatchSnapshot();
});

您是否尝试过为组件提供存根notes.fetch函数

Let isFetched = false;
const fakeNotes = {
  fetch: () => isFetched = true
}
这样,您就可以在不发出请求的情况下测试是否调用了fetch。我不确定,但测试运行程序正在节点中运行,我认为您可能需要在节点中获取,因此真正的注释可能试图使用不存在的浏览器获取


我不是专家,但我相信使用假药来治疗副作用/依赖性是一种好的做法,除非测试特别是测试副作用/相关性。

从错误中可以明显看出,在测试时,您没有提供
组件中使用的道具
注释
将挂载
功能。在创建测试实例时传递它,它应该可以工作

你需要做的就是这样

const notes = {
    fetch: jest.fn() 
}
const tree = renderer.create(
    <myComponent.WrappedComponent notes={notes}/>).toJSON();
     expect(tree).toMatchSnapshot();
});
const注释={
fetch:jest.fn()
}
const tree=renderer.create(
).toJSON();
expect(tree.toMatchSnapshot();
});
您还需要注意的一点是,组件名称必须以大写字符开头

class MyComponent extends React.Component {

      constructor(props) {
        super(props);
        this.state = {
          column: this.getColumns(),
          pageNotFound: false
        };
      }


      componentWillMount() {
        this.props.notes.fetch(this.props.courseId);
        window.addEventListener('resize', this.handleResizeEvent);
        this.handleError = EventBus.on(constants.NOTES_NOT_FOUND, () => {
          this.setState({ pageNotFound: true });
        });
      }

      componentDidMount() {
        window.addEventListener('resize', this.handleResizeEvent);
      }

      componentWillUnmount() {
        window.removeEventListener('resize', this.handleResizeEvent);
        this.handleError();
      }

      handleResizeEvent = () => {
        this.setState({ column: this.getColumns() });
      };

      getColumns = () => (window.innerWidth > (constants.NOTES_MAX_COLUMNS * constants.NOTES_WIDTH) ?
        constants.NOTES_MAX_COLUMNS :
        Math.floor(window.innerWidth / constants.NOTES_WIDTH))

      callback = (msg, data) => {
      }
      render() {
        const { notes, language } = this.props;
        if (this.state.pageNotFound) {
          return (<div className="emptyMessage"><span>Empty</span></div>);
        }
        if (notes.loading) {
          return (<Progress/>);
        }
        // To Refresh Child component will receive props
        const lists = [...notes.cards];
        return (
          <div className="notesContainer" >
            <NoteBook notesList={lists} callback={this.callback} coloums={this.state.column} />
          </div>
        );
      }
    }

MyComponent.propTypes = {
  notes: PropTypes.object,
  courseId: PropTypes.string,
  language: PropTypes.shape(shapes.language)
};
export default withRouter(MyComponent);
类MyComponent扩展了React.Component{ 建造师(道具){ 超级(道具); 此.state={ column:this.getColumns(), pageNotFound:false }; } 组件willmount(){ this.props.notes.fetch(this.props.courseId); window.addEventListener('resize',this.handleResizeEvent); this.handleError=EventBus.on(找不到常量.NOTES,()=>{ this.setState({pageNotFound:true}); }); } componentDidMount(){ window.addEventListener('resize',this.handleResizeEvent); } 组件将卸载(){ window.removeEventListener('resize',this.handleResizeEvent); 这个.handleError(); } HandlerResizeEvent=()=>{ this.setState({column:this.getColumns()}); }; getColumns=()=>(window.innerWidth>(constants.NOTES\u MAX\u COLUMNS*constants.NOTES\u WIDTH)? 常量.NOTES\u MAX\u列: 数学地板(window.innerWidth/constants.NOTES\u WIDTH)) 回调=(消息,数据)=>{ } render(){ const{notes,language}=this.props; if(this.state.pageNotFound){ 返回(空); } 如果(注意:装载){ 返回(); } //刷新子组件将收到道具 const list=[…notes.cards]; 返回( ); } } MyComponent.propTypes={ 注意:PropTypes.object, courseId:PropTypes.string, 语言:PropTypes.shape(shapes.language) }; 使用路由器导出默认值(MyComponent);
将注释作为道具传递给组件,如
,并选中
this.props.notes&&this.props.notes.fetch
,这样即使未传递道具,也不会出现错误。

看起来组件不会使用“this.props.myMaterials”。myMaterials作为道具传入的位置在哪里?抱歉,更新了代码。您拥有的默认道具是什么?请提供组件的完整代码。您能提供完整代码吗?嘿@corey,我还处于react和jest的初级阶段。我试着按照您的建议提供道具,但我仍然存在问题:(谢谢。但是,如果我添加fetch,那么我会得到如下错误类型错误:无法在Function.from(native)将未定义或null转换为object。对此有任何输入吗?抱歉,我没有正确理解您的问题,您在哪里使用fetch?正如您所说,但当我这样给出时,您可以尝试
console.log吗(this.props.notes.fetch)
在component中安装组件,然后使用
运行测试是的,我做了控制台日志,但仍然有相同的错误MyComponent.jsx:104{