Reputation: 740
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
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