问题
I call the react-navigation NavigationService within a redux action. Testing the action I need to mock the navigate function.
/app/utils/NavigationService.js
import { NavigationActions } from 'react-navigation';
let navigator;
function setTopLevelNavigator(navigatorRef) {
navigator = navigatorRef;
}
function navigate(routeName, params) {
navigator.dispatch(NavigationActions.navigate({
type: NavigationActions.NAVIGATE,
routeName,
params,
}));
}
// add other navigation functions that you need and export them
export default {
navigate,
setTopLevelNavigator,
};
I created a __mock__
folder immediately adjacent to the NavigationService.js file.
app/utils/__mocks__/NavigationService.js
UPDATED
const navigate = jest.fn();
const setTopLevelNavigator = jest.fn();
export default {
navigate,
setTopLevelNavigator,
};
Why doesn´t jest auto-mock the navigate
function when the test is run?
https://jestjs.io/docs/en/manual-mocks
__tests__/actions/AuthActions.test.js
UPDATED
jest.mock('../../app/utils/NavigationService'); //at the top directly behind other imports
it('should call firebase on signIn', () => {
const user = {
email: 'test@test.com',
password: 'sign',
};
const expected = [
{ type: types.LOGIN_USER },
{ payload: 1, type: types.DB_VERSION },
{ payload: 'prod', type: types.USER_TYPE },
{ payload: { name: 'data' }, type: types.WEEKPLAN_FETCH_SUCCESS },
{ payload: { name: 'data' }, type: types.RECIPELIBRARY_FETCH_SUCCESS },
{
payload: { user: { name: 'user' }, userVersionAndType: { dbVersion: 1, userType: 'prod' } },
type: types.LOGIN_USER_SUCCESS,
},
];
return store.dispatch(actions.loginUser(user)).then(() => {
expect(store.getActions()).toEqual(expected);
});
});
app/actions/AuthActions.js
export const loginUser = ({ email, password }) => (dispatch) => {
dispatch({ type: LOGIN_USER });
return firebase
.auth()
.signInWithEmailAndPassword(email, password)
.catch((signInError) => {
dispatch({ type: CREATE_USER, payload: signInError.message });
return firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then(async (user) => {
const userVersionAndType = await dispatch(initUser());
await dispatch(initWeekplan(userVersionAndType));
await dispatch(initRecipeLibrary(userVersionAndType));
return user;
});
})
.then(async (user) => {
saveCredentials(email, password);
const userVersionAndType = await dispatch(getUserVersionAndType());
await dispatch(weekplanFetch(userVersionAndType));
await dispatch(recipeLibraryFetch(userVersionAndType));
dispatch(loginUserSuccess({ user, userVersionAndType }));
NavigationService.navigate('Home');
})
.catch(error => dispatch(loginUserFail(error.message)));
};
回答1:
You've create a manual mock for a user module.
Activating a manual mock of a user module for a particular test file requires a call to jest.mock
.
For this particular case add this line to the top of __tests__/actions/AuthActions.test.js
and the mock will be used for all tests within that test file:
jest.mock('../../app/utils/NavigationService'); // use the manual mock in this test file
Note that manual mocks for user modules and Node core modules (like fs
, path
, util
, etc.) both have to be activated for a particular test file by a call to jest.mock
, and that this behavior is different than manual mocks for Node modules which are automatically applied to all tests.
来源:https://stackoverflow.com/questions/55319581/why-isn%c2%b4t-mock-from-mock-folder-invoked-when-running-test-for-redux-action