- use Jest Runner extension: [link]
ShallowWrapper {
...
Symbol(enzyme.__node__) {
props: { // use this to search for item with property:value pair. Ex: wrapper.find('MenuItem[title="View"]')
children: [{}],
...others
},
type: {
displayName: string, // this should be the thing to find.
}
}
...
}
let wrapper = mount(<TextField type='text' required />);
const input = wrapper.find('input');
input.simulate('blur', { target: { value: '' } });
console.log(wrapper.debug());
const icon = wrapper.find('FontAwesomeIcon');
expect(icon).toHaveLength(1);
NEVER REUSE 'find' result. State will not be updated.
Mock children react component of Component-Under-Test (CUT): Find import path of to-be-mocked children, mock in test like below:
Case 1:
ChildComponent.tsx:
....
export const A;
export const B;
jest.mock('path/to/childComponent', () => {
return {
A: true, // return the real implementation of 'A'
B: 'MockB', // return mock of 'B', will be '<MockB />' when shallow
}
});
Case 2: ChildComponent.tsx:
... export const A;
export default B;
jest.mock('path/to/childComponent', () => {
return {
__esModule: true, // MUST SPECIFY
A: true, // return the real implementation of 'A'
default: () => <div> </div>
}
});
const refObj: React.MutableRefObject<Record<string, unknown> = {
current: {},
};
const mockedUseRef = jest.fn(obj => {
refObj.current = obj;
return refObj;
});
jest.mock('../../../config/i18next', () => {
return {
__esModule: true,
default: {
exists: () => true,
t: (key) => `t(${key})`,
}
}
});
import axios from "axios";
const mockApi = new MockAdapter(axios);
it('..', () => {
mockApi.onAny().reply(500);
// assertion
mockAPi.reset()
});
Spy on api:
const apiSpy = spyOn(apiService, "get");
expect (apiSpy).toHaveBeenCalledWith([..]);
! mockAPI and spyOn does not work in the same test case
- mock:
const asyncMethod = jest.fn().mockResolvedValue('abc');
- useFakeTimers:
jest.useFakeTimers();
component.props().onSearch(value);
jest.runAllTimers();
expect(asyncMethod).toBeCalledWith('abc');
jest.mock('moment', () => {
const moment = jest.requireActual('moment');
return {default: moment };
});
it('returns error', async () => {
const apiCall = async () =>
await get(endpoint, {
param: 'yee',
});
await expect(apiCall()).rejects.toThrow();
});
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { runSaga as reduxRunSaga, stdChannel } from 'redux-saga';
const mockApi = new MockAdapter(axios);
it('waits and dispatches', async () => {
mockApi.onPost().reply(200, mock1);
mockApi.onGet().reply(200, mock2);
const channel = stdChannel();
const actions = [];
const saga = reduxRunSaga(
{
channel,
dispatch: action => {
actions.push(action);
},
getState: () => mockState,
},
sagaUnderTest,
);
channel.put(triggerActionAsync.success(mock1));
await saga.toPromise();
expect(actions).toContainEqual(a);
expect(actions).toContainEqual(b);
expect(actions).toContainEqual(c);
});