Jest

You can run a specific test file by using the jest command followed by the name of the test file. This will run all tests in that file.

$ jest myTestFile.spec.js
genMocksFromModule()

Mocks

You can chain mock return values by calling a jest mock function and assigning the return property.

outerMock = jest.fn();
outerMock.mockReturnValue({ innerMock: jest.fn() });
outerMock().innerMock.mockReturnValue("OK");

You can mock the way classes and prototypes interact with the new keyword by setting the mock object’s mockImplementation to be a function that returns the result of the new.

mockClass = jest.fn();
mockClass.mockImplementation(() => {
  return { name: "Belinda" }
});

mockInstance = new mockClass();
mockInstace.name // => Belinda

You can mock global objects (such as the Date) module by patching them directly from the global object.

global.Date.now = jest.fn();
global.Date.now.mockReturnValue("01/09/2018");

Automocks

Jest automocks allow you to generate a mock object automatically from a module. This feature will analyse the module that needs to be mocked and automatically return a mock object which contains mock methods that match the names of the original object. To automock a dependency use the jest.mock function and then import the dependency. It’s important to note that automocks DO NOT define any mock function return types based on the current implementation. This has to be done manually.

In the example below the Dependency object is automocked turning the greet method into a jest.fn automatically which allows for assertions to made against its state, whether it was called, what arguments it received etc. Automocks are useful for large objects as mocking does not need to be done manually and the mock structure will change automatically.

// dependency.js
const Dependency = {
  greet: () => { return "Hello" }
}
module.exports = Dependency;

// dependency.spec.js
jest.mock("./dependency.js");
const Dependency = require("./dependency.js");
it("has mocked the greet method", () => {
	Dependency.greet();
	expect(Dependency.greet).toHaveBeenCalled();
});

You can extend automocks locally to a test suite as you would with any mock.

// dependency.spec.js
jest.mock("./dependency.js");
const Dependency = require("./dependency.js");
it("has mocked the greet method", () => {
	Dependency.greet.mockReturnValue("Hello");
	expect(Dependency.greet()).toEqual("Hello");
});

You can extend automocks in a persistent manner across multiple test suites with a manual mock by creating a __mocks__ folder in the same directory as the module that is automocked and then generating an automocked version of the module, extending it, and then exporting it. When you can jest.mock on that module from a test file, the extended mock from the __mocks__ folder will be used. In the example below the greet method is extended with a mock return value. This return value will be available in any test suite automocks this module.

// __mocks__/dependency.js
let Dependency = genMockFromModule("../dependency.js");
Dependency.greet.mockReturnValue("Hello");
module.exports = Dependency;

Another potential problem is that automocks persist changes to their data between tests within a single test suite. This means that if you want to temporarily make your mock functions throw an error within a test and then change reset back to their original value as defined in your __mocks__ file, you can’t just import them directly inside your test file. To scope your automock and manual mock objects use the resetModules and require functions inside your tests beforeEach function. The resetModules removes all test specific changes made to the mock and the require within test set up reloads the original implementation leading to a cleaner separation of mock functionality. You should still include your call for jest to mock at the head of the file.

// dependency.spec.js
jest.mock("./dependency.js");

describe("Dependency Test", () => {
  let Dependency;
  beforeEach(() => {
    jest.resetModules();
    Dependecy = require("./dependency.js");
  });
  
  it("has a return value", () => {
	Dependency.greet.mockReturnValue("Hello");
	expect(Dependency.greet()).toEqual("Hello");
  });

  it("has a reset return value", () => {
	expect(Dependency.greet()).toEqual(undefined);
  });
});

You can make instance of automocks extensible and modifiable within tests by creating a “private” mock method on the original mock object, assigning that to a property of the mockImplementation return object and then changing the outer method on a per test basis.

// __mocks__/mockClass
let mockClass = genMockFromModule("../mockClass.js");
mockClass = jest.fn();
mockClass._greet = jest.fn();
mockClass.mockImplementation(() => {
  return { greet: mockClass._greet }
});
module.exports = mockClass;

// mockClass.spec.js
jest.mock("./mockClass");
const mockClass = require("./mockClass");

it("sets a greet return value of an instance for this test", () => {
  mockClass._greet.mockReturnValue("Hello");
  mockInstance = new mockClass();
  expect(mockClass.greet()).toEqual("Hello");
});

Testing Async Functions

You can test an async function by prefacing the asynchronous code with the await keyword and defining the test function as async as well.

it("tests an async function"), async () => {
  let result = await asyncFunctionUnderTest();
  
  expect(result).toBe(true);
});

Mocking Promises

You can mock the resolve value of a successful promise by assigning a Promise.resolve as the mockReturnValue of a mock function containing the value you want promise to resolve to.

const returnValue = { message: "OK" };
let mockFunction = jest.fn();
mockFunction.mockReturnValue(Promise.resolve(returnValue));

You can mock the reject error of a failing promise by assigning a Promise.reject as the mockReturnValue of a mock function containing the error that you want the promise to fail to. IMPORTANT: If you add a Promise.reject to a jest test you must have a catch somewhere in the code you are testing otherwise the test will not be run and will yield no error message.

const error = new Error("Promise failed.");
let mockFunction = jest.fn();
mockFunction.mockReturnValue(Promise.reject(error));

Log Output

You can **show console.log output using the --silent flag set to false. It’s also easier to just run using npx when you want to see console output.

npx jest --silent=false

Also, possibly valid is

npm test --silent=false