Good day! I'm working with Amplitude is a service for monitoring your actions etc.. but returning to my question, at this moment i'm trying to mock this module "amplitude-js" to do Test, but i think i'm mocking in a bad way.. so if someone can help me to do this in the right way i will appreciate. So starting first with the function that i want to do test is this one:
export const signIn = (): ThunkAction<
void,
RootState,
null,
FluxStandardAction
> => {
return async (dispatch, getState) => {
const { username, password } = getState().Authentication;
amplitude.getInstance().logEvent('LOGIN_SIGN_IN_REQUEST'); <=== This
dispatch(signInRequest() as FluxStandardAction<string, any>);
try {
const response = await axios.post(`${API}/users/login`, {
username,
password,
});
const { data } = response;
amplitude.getInstance().logEvent('LOGIN_SIGN_IN_SUCCESS', data); <=== This as well
dispatch(signInSuccess(data.token) as FluxStandardAction<string, any>);
} catch (err) {
Sentry.captureException(err);
dispatch(signInFailure(err) as FluxStandardAction<string, any>);
}
};
};
As you see im using redux to dispatch the action, i did the Test of my function without trying to mock Amplitude and the test is Perfect.. i will share my code of my test that you can see what i have.. remember i only want to test Amplitude, the others values i dont care!!
THE TEST:
jest.mock('axios');
jest.mock('amplitude-js');
import axios from 'axios';
import amplitude from 'amplitude-js';
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { API } from '../../../src/Config';
import * as actions from '../../../src/redux/actions/authentication/authentication';
const middleware = [thunk];
const mockStore = configureStore(middleware);
const store = mockStore({});
const mockT = jest.fn().mockReturnValue('LOGIN_SIGN_IN_REQUEST');
describe('Authentication async action', () => {
describe("'onLogin' actions", () => {
beforeEach(() => {
store.clearActions();
});
it('creates LOGIN_SIGN_IN_SUCCESS on successful authentication', async () => {
const token = 'token';
(axios.post as jest.Mock).mockReset();
(axios.post as jest.Mock).mockResolvedValue({
data: {
token,
},
});
(amplitude.getInstance as any).mockReset();
const expectedActions = [
{
type: actions.LOGIN_SIGN_IN_REQUEST,
},
{
type: actions.LOGIN_SIGN_IN_SUCCESS,
payload: token,
},
];
const store = mockStore({
Authentication: {
username: 'username',
password: 'password',
},
});
await store.dispatch(actions.signIn() as any);
expect(amplitude.getInstance().logEvent('LOGIN_SIGN_IN_REQUEST'));
expect(store.getActions()).toEqual(expectedActions);
expect(axios.post).toHaveBeenCalledWith(`${API}/users/login`, {
username: 'username',
password: 'password',
});
});
So when i run the test in Jest i'm receiving this error:
● Authentication async action › 'onLogin' actions › creates LOGIN_SIGN_IN_SUCCESS on successful authentication
TypeError: Cannot read property 'logEvent' of undefined
103 | return async (dispatch, getState) => {
104 | const { username, password } = getState().Authentication;
> 105 | amplitude.getInstance().logEvent('LOGIN_SIGN_IN_REQUEST');
| ^
106 | dispatch(signInRequest() as FluxStandardAction<string, any>);
107 |
108 | try {
at src/redux/actions/authentication/authentication.ts:105:5
If i call this:
describe('Authentication async action', () => {
describe("'onLogin' actions", () => {
beforeEach(() => {
store.clearActions();
});
it('creates LOGIN_SIGN_IN_SUCCESS on successful authentication', async () => {
const token = 'token';
(axios.post as jest.Mock).mockReset();
(axios.post as jest.Mock).mockResolvedValue({
data: {
token,
},
});
(amplitude.getInstance() as any).mockReset(); <=== i call getsIstance()
const expectedActions = [
{
type: actions.LOGIN_SIGN_IN_REQUEST,
},
{
type: actions.LOGIN_SIGN_IN_SUCCESS,
payload: token,
},
];
const store = mockStore({
Authentication: {
username: 'username',
password: 'password',
},
});
await store.dispatch(actions.signIn() as any);
expect(amplitude.getInstance().logEvent('LOGIN_SIGN_IN_REQUEST'));
expect(store.getActions()).toEqual(expectedActions);
expect(axios.post).toHaveBeenCalledWith(`${API}/users/login`, {
username: 'username',
password: 'password',
});
});
Now i received this error:
TypeError: Cannot read property 'mockReset' of undefined
36 | });
37 |
> 38 | (amplitude.getInstance() as any).mockReset();
| ^
39 |
40 | const expectedActions = [
41 | {
at Object.<anonymous> (test/redux/Authentication/Authentication.action.async.test.ts:38:7)
Quite annoying..
Maybe is something easy to mock.. but i don't have a lot of experience doing test!