Skip to content

Instantly share code, notes, and snippets.

@jenniferlynparsons
Created June 7, 2019 19:05
Show Gist options
  • Save jenniferlynparsons/da7dc004bcf868d15ab7f1f545f8977e to your computer and use it in GitHub Desktop.
Save jenniferlynparsons/da7dc004bcf868d15ab7f1f545f8977e to your computer and use it in GitHub Desktop.
A bit about Jest mocks
import setAuthToken from "../utils/setAuthToken";
import jwt_decode from "jwt-decode";
import API from "../lib/api";
import { authActionTypes } from "../lib/actionTypes";
// Login - get user token
export const loginAction = userData => {
return dispatch => {
API.post("/users/login", userData).then(response => {
const { token } = response;
localStorage.setItem("jwtToken", token);
setAuthToken(token);
const decoded = jwt_decode(token);
//check that setCurrentUser is called with decoded
dispatch(authActions.setCurrentUser(decoded));
});
};
};
export const setCurrentUser = decoded => {
return {
type: authActionTypes.SET_CURRENT_USER,
payload: decoded
};
};
const authActions = {
loginAction,
setCurrentUser
};
export default authActions;
import { makeMockStore } from "../../test/testUtils";
import authActions from "../authActions";
import jwt_decode from "jwt-decode";
import API from "../../lib/api";
import setAuthToken from "../../utils/setAuthToken";
// CREATING A MOCK STORE AND FAKED DATA
const store = makeMockStore({
auth: {
isAuthenticated: false,
user: {},
loading: false
}
});
const mockLoginData = {
email: "test@example.com",
password: "testpassword"
};
const mockResponse = {
success: true,
token:
"Bearer eyJhbGciOiJIUzI.eyJpZCI6IjVjN.1Tn8FLJEGGE8"
};
// CREATING MOCKS
jest.mock("../../utils/setAuthToken", () => jest.fn());
jest.mock("jwt-decode");
jest.mock("../../lib/api", () => ({
post: jest.fn(() => Promise.resolve(mockResponse))
}));
// JEST TESTS
describe("loginAction", () => {
test("returns a function", () => {
expect(authActions.loginAction(mockLoginData)).toBeInstanceOf(Function);
});
describe("dispatching the returned function", () => {
test("it calls 'post' on the API with the correct path and the user data", () => {
store.dispatch(authActions.loginAction(mockLoginData));
expect(API.post).toHaveBeenCalledWith("/users/login", mockLoginData);
});
describe("when the POST call is successful", () => {
test("it sets the JWT token to the response from the POST", async () => {
await store.dispatch(authActions.loginAction(mockLoginData));
expect(setAuthToken).toHaveBeenCalledWith(mockResponse.token);
});
test("it decodes the token with jwt_decode", async () => {
await store.dispatch(authActions.loginAction(mockLoginData));
expect(jwt_decode).toHaveBeenCalledWith(mockResponse.token);
});
test("it sets the current user action", async () => {
let currentUserSpy = jest.spyOn(authActions, "setCurrentUser");
await store.dispatch(authActions.loginAction(mockLoginData));
expect(currentUserSpy).toHaveBeenCalledTimes(1);
});
});
});
});
import React from "react";
import { Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";
const PrivateRoute = ({ component: Component, auth, ...rest }) => (
<Route
{...rest}
render={props =>
auth.isAuthenticated === true ? (
<Component {...props} />
) : (
<Redirect to="/login" />
)
}
/>
);
const mapStateToProps = state => ({
auth: state.auth
});
export default connect(mapStateToProps)(PrivateRoute);
import React from "react";
import { Redirect } from "react-router-dom";
import { MemoryRouter } from "react-router";
import { mount } from "enzyme";
import { makeMockStore } from "../../../../test/testUtils";
import { GenericComponent } from "../../../../test/__mocks__/GenericComponent";
import PrivateRoute from "../PrivateRoute";
const loggedOutState = {
auth: {
isAuthenticated: false
}
};
jest.mock("react-router-dom", () => {
const original = jest.requireActual("react-router-dom");
return {
...original,
Redirect: jest.fn().mockImplementation(() => null)
};
});
describe("PrivateRoute rendering", () => {
test("PrivateRoute should redicted to the login page if user is logged out", () => {
const store = makeMockStore(loggedOutState);
let wrapper = mount(
<MemoryRouter initialEntries={["/dashboard"]} initialIndex={0}>
<PrivateRoute
path="/dashboard"
component={GenericComponent}
store={store}
/>
</MemoryRouter>
);
expect(wrapper.find(Redirect).exists()).toBe(true);
});
});
@vinnihoke
Copy link

Hey Jennifer! Can you elaborate on makeMockStore and what that is doing?

@jenniferlynparsons
Copy link
Author

Hey Jennifer! Can you elaborate on makeMockStore and what that is doing?

Sure! You can see the internals of it here: https://github.com/jenniferlynparsons/cuppa/blob/9594c14f2ed993f857a69a62c256156536899ff5/client/src/test/testUtils.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment