Jest has a similar structure to Jasmine.
describe("<MeaningOfLife />", () => {
describe("askQuestion", () => {
let answer;
beforeEach(() => {
answer = askQuestion();
});
it("gives the answer to everthing", () => {
expect(answer).toEqual(42);
});
});
});Here are the docs with a complete list of matchers.
expect(value).toEqual(23);
expect(arr).toHaveLength(5);
expect(nullVal).toBeNull();
expect(myObj).toHaveProperty("firstName", "JimBob");
expect(myObj.foo).toBeUndefined();
expect(result).toBeCloseTo(3.14159);You can negate any of them with the not method chain:
expect(value).not.toEqual(23);If you want to focus an it or a describe section, use only
it.only("verifies coolness", () => {
const coolSpy = jest.spyOn(elliotIs, "cool");
elliotIs.cool();
expect(coolSpy).toHaveBeenCalled();
});You can mock a method and then test that it was called:
const doSomething = jest.fn();
it("did something", () => {
doSomething('please');
expect(doSomething.mock.calls.length).toEqual(1);
expect(doSomething.mock.calls[0][0]).toEqual("please");
expect(doSomething).toHaveBeenCalledTimes(1);
expect(doSomething).toHaveBeenCalledWith("please");
});You can also spy on a method:
const elliotIs = { cool: () => {} };
it("verifies coolness", () => {
const coolSpy = jest.spyOn(elliotIs, "cool");
elliotIs.cool();
expect(coolSpy).toHaveBeenCalled();
});Creates a mock function similar to jest.fn but also tracks calls to object[methodName]. Returns a Jest mock function.
Note: By default, jest.spyOn also calls the spied method. This is different behavior from most other test libraries.
mockClear resets all information stored in the mockFn.mock.calls and mockFn.mock.instances arrays.
Often this is useful when you want to clean up a mock's usage data between two assertions.
const mockFn = jest.fn();
// some tests
mockFn.mockClear()mockReset resets all information stored in the mock, including any initial implementation and mock name given.
This is useful when you want to completely restore a mock back to its initial state.
const mockFn = jest.fn();
// some tests
mockFn.mockReset()mockRestor removes the mock and restores the initial implementation.
This is useful when you want to mock functions in certain test cases and restore the original implementation in others.
const mockFn = jest.fn();
// some tests
mockFn.mockRestor()Note:
jest.fn(implementation)is a shorthand forjest.fn().mockImplementation(implementation)
You can add a standin implementation for a mock
const meaningOfLife = jest.fn(() => 42);You can also mock the implementation once, so the first time the mock is called, it will return the mock implementation, and then after that, the original functionality is used. These can be chanined:
const meaningOfLife = jest
.fn(() => "I mean, it's a silly question, really")
.mockImplementationOnce(() => "42")
.mockImplementationOnce(() => "I mean it, 42")
console.log(meaningOfLife(), meaningOfLife(), meaningOfLife(), meaningOfLife())
// => 42
// => I mean it, 42
// => I mean, it's a silly question, really
// => I mean, it's a silly question, reallyYou can use mockReturnValue instead of jest.fn(() => 42)
const mock = jest.fn().mockReturnValue(42);
mock(); // 42If you are testing a class that has imports you would like to mock out, you can use jest.mock
Implementation:
import knowledge from "google";
class MeaningOfLife {
ask() {
const googleThinks = knowlege.meaningOfLife;
return `${googleThinks}, or 42`;
}
}Test, this mocks out google in the implementation file.
import MeaningOfLife from "./meaning-of-life";
import knowledge from "google";
jest.mock("google");To execute the whole suite
$ jest testTo execute the whole suite with coverage
$ jest test --coverageThis will create a coverage report in coverage/lcov-report/index.html
To run the suite in watch mode, where it will re-run everytime a file is saved
$ jest test --watchAllTo run for a single file
$ jest test MyComponent.spec.jsTo watch the one file
$ jest test --watch MyComponent.spec.jsUsing the Enzyme library from AirBnb can help make React component testing better.
Snapshot testing with Enzyme is a bit simpler than with vanilla Jest
describe("<Foo />", () => {
let wrapper;
beforeEach(() => {
wrapper = shallow(<Foo />);
});
describe("snapshot", () => {
it("renders correctly", () => {
expect(wrapper).toMatchSnapshot();
});
});
});Once you've used shallow to render the component, you can interact with it in a few useful ways.
wrapper.setState({ foo: "bar" });wrapper.state("foo");wrapper.setProps({ foo: "bar" });The shallow render is just a shallow rendered instance of the component class. The instance of this object is available with wrapper.instance(). Off of this you can work with methods and data on the class.
This can be useful for properties that are not a part of the object's state
class Foo extends Component {
constructor(props) {
super(props);
this.foo = "bar";
}
}
// ... then in your test
wrapper.instance().foo; // barThis can also be a useful way to mock out methods
class Foo extends Component {
myMethod() {
// does some stuff
}
}
// ... then in your test
const myMethodMock = jest.fn();
wrapper.instance().myMethod = myMethodMock;
// ... some testing stuff that calls myMethod()
expect(myMethodMock).toHaveBeenCalledTimes(1);You can also use the shallow wrapper to find rendered elements and simulate events on them
wrapper.find("button").simulate("click");
expect(onButtonClickMock).toHaveBeenCalledTimes(1);The mount renderer does a full DOM render. You need this if you are testing methods that deal with references.
describe("mouseEnterHandler", () => {
it("sets the style transform property of myRef", () => {
wrapper = mount(<Foo {...defaultProps} />);
wrapper.instance().mouseEnterHandler("event-stub");
expect(
wrapper.instance().myRef.current.style.transform
).toEqual("rotate(0deg) translate(-50%, -50%)");
});
});