Reactjs 浅薄笑话前的模拟函数或变量

Reactjs 浅薄笑话前的模拟函数或变量,reactjs,react-native,jestjs,enzyme,Reactjs,React Native,Jestjs,Enzyme,我正试图编写jest来测试我的组件。但是一旦调用了shall,我的测试就失败了,因为调用fetchUsers函数时会说cannotreadproperty get of null(这似乎是myRequestor的初始值)。它无法在MyComponent内的MyReqUtil功能组件中初始化myRequestor的值。看起来它没有调用此函数或它没有初始化值。我陷入了这个困境,因为我无法编写测试,每次它在我使用shallow的第一行失败。有人能帮我吗这个 MyComponent.jsx let my

我正试图编写jest来测试我的组件。但是一旦调用了shall,我的测试就失败了,因为调用fetchUsers函数时会说cannotreadproperty get of null(这似乎是myRequestor的初始值)。它无法在MyComponent内的MyReqUtil功能组件中初始化myRequestor的值。看起来它没有调用此函数或它没有初始化值。我陷入了这个困境,因为我无法编写测试,每次它在我使用shallow的第一行失败。有人能帮我吗这个

MyComponent.jsx

let myRequestor = null;

 const MyReqUtil = () => {
 myRequestor = React.useContext(MyRequestorContext);
 return <ApplicationLoadingOverlay isOpen backgroundStyle="clear" />;
};


class MyComponent extends React.Component {

componentDidMount() {
  this.setState({ isLoading: true });
  this.fetchUsers();
}

fetchUsers() {
this.setState({ isLoading: true });
const { request } = myRequestor.get({
  url: '/users',
});

request
  .then(({ data }) => {
    if (Object.prototype.hasOwnProperty.call(data[0], 'error')) {
      this.setState({
        error: 'Failure', errorMsg: data[0].error, isOpen: true, isLoading: false, userItems: [{ name: 'DEFAULT', id: 'Default' }],
      });
      return;
    }

    const users = data.map(user => ({
      name: user.shortName,
      id: user.key,
    }));

    this.setState({
      userItems: users, isLoading: false,
    });
  })
  .catch((error) => {
    console.log(error);
    this.setState({ error: 'Failure', isOpen: true, isLoading: false });
  });
 }

 render() {

   if (this.state.tenantItems === null) {
      return <MyReqUtil />;
   }
}
让myRequestor=null;
常量MyReqUtil=()=>{
myRequestor=React.useContext(MyRequestorContext);
返回;
};
类MyComponent扩展了React.Component{
componentDidMount(){
this.setState({isLoading:true});
this.fetchUsers();
}
fetchUsers(){
this.setState({isLoading:true});
const{request}=myRequestor.get({
url:“/users”,
});
要求
。然后({data})=>{
if(Object.prototype.hasOwnProperty.call(数据[0],'error')){
这是我的国家({
错误:“失败”,errorMsg:data[0]。错误,isOpen:true,isLoading:false,userItems:[{name:'DEFAULT',id:'DEFAULT'}],
});
返回;
}
const users=data.map(user=>({
名称:user.shortName,
id:user.key,
}));
这是我的国家({
userItems:users,isLoading:false,
});
})
.catch((错误)=>{
console.log(错误);
this.setState({error:'Failure',isOpen:true,isLoading:false});
});
}
render(){
if(this.state.tenantItems===null){
返回;
}
}
MyComponent.test.jsx

describe('<MyComponent />', () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<MyComponent />);
  });

     it('should check `componentDidMount()`', () => {
        const instance = wrapper.instance();
        jest.spyOn(instance, 'fetchUsers');
        instance.componentDidMount();
        expect(instance.fetchUsers).toHaveBeenCalledTimes(1);
     });

   it('Should Render Component Correctly', () => {
    const spy = jest.spyOn(OrionReqUtil, 'fetchUsers');
    const wrapper = shallow(<MyComponent />);
    const instance = wrapper.instance();
    spy.mockReturnValue(['mockItem1', 'mockItem2', 'mockItem3']);

   });
});
描述(“”,()=>{
让包装纸;
在每个之前(()=>{
包装器=浅();
});
它('应该选中'componentDidMount()',()=>{
const instance=wrapper.instance();
spyOn(实例'fetchUsers');
componentDidMount();
expect(instance.fetchUsers).toHaveBeenCalledTimes(1);
});
它('应该正确呈现组件',()=>{
constspy=jest.spyOn(OrionReqUtil,'fetchUsers');
常量包装器=浅();
const instance=wrapper.instance();
spy.mockReturnValue(['mockItem1','mockItem2','mockItem3']);
});
});

该测试在每个之前的
中执行了两次
shall()
,这可能是一个错误。如果测试没有在每个
之前的
中完全共享代码,则应将其移至测试

这是
disableLifecycleMethods
选项的情况,它允许在准备实例时手动调用
componentDidMount

wrapper = shallow(<MyComponent />, { disableLifecycleMethods: true });
jest.spyOn(wrapper.instance(), 'fetchUsers').mockReturnValue(...);
wrapper.instance().componentDidMount();

通过这种方式,它可以作为一个单独的单元进行全面测试。
MyComponent
可以进行全面测试,因为依赖项可以作为道具使用,因此可以进行模拟。

在一个地方是
MyReqUtil
,在另一个地方是
OrionReqUtil
。您在测试中遇到问题是一种症状。实际上,当设计不好时就是这种情况这个决定使单元更难测试,需要重构。很抱歉,它实际上是MyReqUtil。我已经编辑了代码。我现在得到以下错误“无法监视fetchUsers属性,因为它不是函数;如果我使用shallow,则会给出未定义的属性。此外,我无法更改主类,是否有方法为同一个类编写测试?”修复了它,它应该是
wrapper.instance()
,而不是
包装器。实例
。如果您无法重构组件,请尝试
装载
渲染
。使用
浅层
@k-wasilewski编写不正确。如果在实例上使用它,则会发生这种情况。因为fetchUsers是proto方法,它也会在proto上工作。proto方法在一些方面更可取ns,只是因为它们更高效,并提供了一个在测试中监视或模拟方法的更多选项。我以前没有使用过render,mount不适用于此测试。请您帮助我如何使用render而不是shall@Estus Flask或cn编写此测试。我只是硬编码fetchUsers函数的任何模拟返回值,以便它不会打电话给我的请求者。获取??
jest.spyOn(MyComponent.prototype, 'fetchUsers').mockReturnValue(...);
wrapper = shallow(<MyComponent />);
const MyReqUtil = (props) => {
  const myRequestor = React.useContext(MyRequestorContext);
  const loaderElement = <ApplicationLoadingOverlay isOpen backgroundStyle="clear" />;

  return <MyComponent loader={loaderElement} requestor={myRequestor} {...props} />
};