'expect(jest.fn()).toHaveBeenCalled()
I want to test that specific method/s are called when the user clicks 'sign in with microsoft' button.
Unfortunately, I'm receiving the below error in the image:
[enter image description here][1]
What I want is to mock the one specific method/instance that cause the sign up with microsoft pop up to occur on button click.
Below is my test file:
Login.test.js:
import * as React from 'react';
import {
render, screen, waitFor
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MuiThemeProvider } from '@material-ui/core';
import { SnackbarProvider } from 'notistack';
import { I18nextProvider } from 'react-i18next';
import Login from '../../pages/Login';
import theme from '../../styles/theme';
import i18n from '../../i18n/index';
const mockLoginWithMicrosoft = jest.fn();
jest.mock('../../config/Firebase', () => ({
__esModule: true,
default: {
getCurrentUserId: jest.fn(),
loginWithMicrosoft: () => mockLoginWithMicrosoft,
}
}));
afterEach(() => {
jest.resetAllMocks();
jest.restoreAllMocks();
});
test('Firebase signInWithPopUp triggered on login button ', async () => {
render(
<MuiThemeProvider theme={theme}>
<SnackbarProvider>
<I18nextProvider i18n={i18n}>
<Login />
</I18nextProvider>
</SnackbarProvider>
</MuiThemeProvider>
);
expect(<Login />).toBeTruthy();
userEvent.click(screen.getByRole('button', { name: /sign in with microsoft/i }));
await waitFor(() => expect(mockLoginWithMicrosoft).toHaveBeenCalled());
});
And here is my firebase setup:
Firebase/index.js:
class Firebase {
constructor() {
app.initializeApp(config);
app.analytics();
this.perf = app.performance();
this.auth = app.auth();
this.db = app.firestore();
this.microsoftProvider = new app.auth.OAuthProvider('microsoft.com');
this.microsoftProvider.setCustomParameters({
tenant: '4b9d21d4-5ce6-4db6-bce6-cfcd1920afbc',
});
this.microsoftProvider.addScope('GroupMember.Read.All');
}
async loginWithMicrosoft() {
try {
const result = await this.auth.signInWithPopup(this.microsoftProvider);
const {
accessToken,
} = result.credential;
await this.getUserRoles(accessToken);
this.refreshRoles(true);
return {
message: 'success',
};
} catch (error) {
return {
message: 'failure',
};
}
}
some code
As you see above, I expect loginWithMicrosoft to be called, when clicking login button as shown below in login file:
Login.js:
import { useSnackbar } from 'notistack';
import { Redirect } from 'react-router-dom';
import Button from '@material-ui/core/Button';
import { useTranslation } from 'react-i18next';
import { DASHBOARD as DASHBOARD_PATH } from '../../navigation/CONSTANTS';
import firebase from '../../config/Firebase';
const Login = (props) => {
const { history } = props;
const classes = useStyles(props);
const { enqueueSnackbar } = useSnackbar();
const { t } = useTranslation();
const [loadState, setLoadState] = useState(false);
if (firebase.getCurrentUserId()) {
return (<Redirect to={DASHBOARD_PATH} />);
}
async function login() {
try {
setLoadState(true);
await firebase.loginWithMicrosoft();
history.replace(DASHBOARD_PATH);
} catch (error) {
enqueueSnackbar(t(translationKeys.snackbar.loginFailed), { variant: 'error' });
setLoadState(false);
}
}
return (
<div>
some code
<Button
data-testid="submitbtn"
disabled={loadState}
type="submit"
fullWidth
variant="contained"
color="primary"
startIcon={<img src={MicrosoftIcon} alt="" />}
className={classes.submit}
onClick={() => { login(); }}
>
{t(translationKeys.button.loginWindows)}
</Button>
</Grid>
<Footer />
</Grid>
</div>
);
};
);
};
Any help would be appreciated.
Solution 1:[1]
Okay so someone helped solve this problem,
As it was explained to me,
LoginWithMicrosoft doesn't need to be an arrow function since jest.fn already returns a function
The other problem is jest hoisting the mock call above the fn declaration
My code now looks like this:
import MockFirebase from '../../config/Firebase';
jest.mock('../../config/Firebase', () => ({
__esModule: true,
default: {
getCurrentUserId: jest.fn(),
loginWithMicrosoft: jest.fn(),
}
}));
test('Firebase signInWithPopUp triggered on login button ', async () => {
render(
<MuiThemeProvider theme={theme}>
<SnackbarProvider>
<I18nextProvider i18n={i18n}>
<Login />
</I18nextProvider>
</SnackbarProvider>
</MuiThemeProvider>
);
userEvent.click(screen.getByRole('button', { name: /sign in with microsoft/i }));
expect(MockFirebase.loginWithMicrosoft).toHaveBeenCalled();
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Samora Mabuya |
