在React.js中使用Jest对异步函数进行存根

时间:2018-09-30 06:32:38

标签: reactjs jestjs

我刚刚开始使用Jest和酶进行Reactjs测试。我正在使用异步函数来获取componentDidMount中的数据。我正在尝试模拟getData函数,但是在函数求解时失败。

export class ListNamespaces extends React.Component<IListNamespacesProps, IListNamespacesState> {

  constructor(props: IListNamespacesProps) {
    super(props);
  }

  componentDidMount() {
    this.getAllData()
      .then((response: Types.ListNamespacesResponse) => {
        this.setState({
          ...
        })
      });
  }

  getAllData() {
    this.setState({
      isLoading: true
    });

    const client = new Client();
    return client.getAlldata();
  }

  ...
}

export class Client { 

  public getAlldata() {
    //async call
  }

}


describe('ListNamespaces', () => {
  test("Shallow Render matches initial snapshot", () => {
    const listNamespaceView = <ListNamespaces/>;
    listNamespaceView.prototype.getAllNamespaces = jest.fn();
    const listNamespacesShallowView = shallow(listNamespaceView);
    expect(listNamespacesShallowView).toMatchSnapshot();
  });
});    

错误-

TypeError: Cannot read property 'then' of undefined

  138 | 
  139 |   componentDidMount() {
> 140 |     this.getAllData()
  141 |       .then((response: Types.ListNamespacesResponse) => {
  142 |         ...

  at ListNamespaces.Object.<anonymous>.ListNamespaces.componentDidMount (src/modules/bulk-namespace/views/list-namespaces.tsx:140:28)
  at node_modules/enzyme/build/ShallowWrapper.js:215:22
  at Object.batchedUpdates (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:474:22)
  at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:214:26)
  at Object.shallow (node_modules/enzyme/build/shallow.js:21:10)
  at Object.<anonymous> (tst/modules/bulk-namespace/list-namespaces.tsx:10:39)

如何正确模拟此功能。

1 个答案:

答案 0 :(得分:2)

您需要模拟Client类。当getAlldata返回一个承诺并且您需要等待该承诺在测试中得到解决时,解决方案可能如下所示:

// first mock the module so it will return a jest mock
jest.mock('./path/to/client', () => jest.fn())

// import the mocked module
import Client from './path/to/client'

// create a promise
const result = Promise.resolve({some: 'result'})
// now mock Client so it will behave like your class 
//  and make `getAlldata` return it
client.mockReturnValue(()=> ({getAllData: ()=> result}))


describe('ListNamespaces',() => {
  // create a `async` test function so you can wait for the result promise
  test("Shallow Render matches initial snapshot", async() => {
    const listNamespacesShallowView = shallow(<ListNamespaces/>);
    // wait for the promise to be resolved
    await result
    expect(listNamespacesShallowView).toMatchSnapshot();
  });
});   

令人困惑的部分是,您必须创建一个已解决的承诺,但仍然必须在测试本身中等待它。