user2696466
user2696466

Reputation: 740

Stub a async function using Jest in reactjs

I have just started using Jest and enzymes for Reactjs testing. I am using a async function to fetch data inside componentDidMount. I am trying to mock getData function but its failing when function is solving.

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();
  });
});    

Error -

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)

How to mock this function properly.

Upvotes: 1

Views: 1015

Answers (1)

Andreas K&#246;berle
Andreas K&#246;berle

Reputation: 111062

You need to mock the Client class. As getAlldata returns a promise and you need to wait for this promise to be resolved in the test, a solution could look like this:

// 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();
  });
});   

The confusing part is, that you have to create a resolved promise but still have to wait for it in the test itself.

Upvotes: 2

Related Questions