Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
The jest-when package is an extension for Jest that allows for more readable and maintainable mock function behavior. It provides a way to define mock implementations based on specific argument conditions, making it easier to set up complex mocks.
Mocking based on arguments
This feature allows you to define different return values for a mock function based on the arguments it is called with. This makes it easier to handle multiple scenarios in your tests.
const { when } = require('jest-when');
const mockFn = jest.fn();
when(mockFn).calledWith(1).mockReturnValue('one');
when(mockFn).calledWith(2).mockReturnValue('two');
console.log(mockFn(1)); // 'one'
console.log(mockFn(2)); // 'two'
console.log(mockFn(3)); // undefined
Mocking based on multiple arguments
This feature allows you to define return values for a mock function based on multiple arguments, providing more granular control over the mock behavior.
const { when } = require('jest-when');
const mockFn = jest.fn();
when(mockFn).calledWith(1, 'a').mockReturnValue('one-a');
when(mockFn).calledWith(2, 'b').mockReturnValue('two-b');
console.log(mockFn(1, 'a')); // 'one-a'
console.log(mockFn(2, 'b')); // 'two-b'
console.log(mockFn(1, 'b')); // undefined
Mocking with custom matchers
This feature allows you to use Jest's built-in matchers to define mock behavior, making it easier to handle a wide range of input scenarios.
const { when } = require('jest-when');
const mockFn = jest.fn();
when(mockFn).calledWith(expect.any(Number)).mockReturnValue('number');
when(mockFn).calledWith(expect.any(String)).mockReturnValue('string');
console.log(mockFn(123)); // 'number'
console.log(mockFn('abc')); // 'string'
console.log(mockFn(true)); // undefined
Sinon is a popular standalone test spy, stub, and mock library for JavaScript. It provides similar functionality to jest-when but is more comprehensive, offering a wider range of features for test doubles. Unlike jest-when, Sinon is not specifically designed for Jest and can be used with other testing frameworks.
Testdouble is a library for creating test doubles (mocks, stubs, and spies) in JavaScript. It offers a similar feature set to jest-when but is designed to be framework-agnostic, meaning it can be used with various testing frameworks, not just Jest. Testdouble focuses on providing a simple and intuitive API for creating and managing test doubles.
An extended, sugary way to mock return values for specific arguments only
Many thanks to @jonasholtkamp. He forked this repo when I was inactive and stewarded several key features and bug fixes!
jest-when
allows you to use a set of the original
Jest mock functions in order to train
your mocks only based on parameters your mocked function is called with.
An example statement would be as follows:
when(fn).calledWith(1).mockReturnValue('yay!')
The trained mock function fn
will now behave as follows -- assumed no other trainings took place:
yay!
if called with 1
as first parameterundefined
if called with any other first parameter than 1
For extended usage see the examples below.
The supported set of mock functions is:
mockReturnValue
mockReturnValueOnce
mockResolvedValue
mockResolvedValueOnce
mockRejectedValue
mockRejectedValueOnce
mockImplementation
mockImplementationOnce
npm i --save-dev jest-when
import { when } from 'jest-when'
const fn = jest.fn()
when(fn).calledWith(1).mockReturnValue('yay!')
expect(fn(1)).toEqual('yay!')
when(fn)
.calledWith(1).mockReturnValue('yay!')
.calledWith(2).mockReturnValue('nay!')
expect(fn(1)).toEqual('yay!')
expect(fn(2)).toEqual('nay!')
Thanks to @fkloes.
when(fn)
.calledWith(1)
.mockReturnValueOnce('yay!')
.mockReturnValue('nay!')
expect(fn(1)).toEqual('yay!')
expect(fn(1)).toEqual('nay!')
Thanks to @danielhusar.
when(fn).calledWith(1).mockReturnValue('yay!')
expect(fn(1)).toEqual('yay!')
when(fn).calledWith(1).mockReturnValue('nay!')
expect(fn(1)).toEqual('nay!')
This replacement of the training does only happen for mock functions not ending in *Once
.
Trainings like mockReturnValueOnce
are removed after a matching function call anyway.
Thanks to @fkloes.
when(fn).calledWith(1, true).mockReturnValue('yay!')
expect(fn(1, true)).toEqual('yay!')
expect(fn(1, true, 'foo')).toEqual('yay!')
when(fn).calledWith(1, true, 'foo').mockReturnValueOnce('yay!')
when(fn).calledWith(1, true, 'foo').mockReturnValueOnce('nay!')
expect(fn(1, true, 'foo')).toEqual('yay!')
expect(fn(1, true, 'foo')).toEqual('nay!')
expect(fn(1, true, 'foo')).toBeUndefined()
when(fn).calledWith(1).mockResolvedValue('yay!')
when(fn).calledWith(2).mockResolvedValueOnce('nay!')
await expect(fn(1)).resolves.toEqual('yay!')
await expect(fn(1)).resolves.toEqual('yay!')
await expect(fn(2)).resolves.toEqual('nay!')
expect(await fn(2)).toBeUndefined()
when(fn).calledWith(3).mockRejectedValue(new Error('oh no!'))
when(fn).calledWith(4).mockRejectedValueOnce(new Error('oh no, an error again!'))
await expect(fn(3)).rejects.toThrow('oh no!')
await expect(fn(3)).rejects.toThrow('oh no!')
await expect(fn(4)).rejects.toThrow('oh no, an error again!')
expect(await fn(4)).toBeUndefined()
const theSpiedMethod = jest.spyOn(theInstance, 'theMethod');
when(theSpiedMethod)
.calledWith(1)
.mockReturnValue('mock');
const returnValue = theInstance.theMethod(1);
expect(returnValue).toBe('mock');
when(fn).calledWith(
expect.anything(),
expect.any(Number),
expect.arrayContaining(false)
).mockReturnValue('yay!')
const result = fn('whatever', 100, [true, false])
expect(result).toEqual('yay!')
when(fn).calledWith(1).mockReturnValue('no')
when(fn).calledWith(2).mockReturnValue('way?')
when(fn).calledWith(3).mockReturnValue('yes')
when(fn).calledWith(4).mockReturnValue('way!')
expect(fn(1)).toEqual('no')
expect(fn(2)).toEqual('way?')
expect(fn(3)).toEqual('yes')
expect(fn(4)).toEqual('way!')
expect(fn(5)).toEqual(undefined)
Use expectCalledWith
instead to run an assertion that the fn
was called with the provided
args. Your test will fail if the jest mock function is ever called without those exact
expectCalledWith
params.
Disclaimer: This won't really work very well with compound declarations, because one of them will always fail, and throw an assertion error.
when(fn).expectCalledWith(1).mockReturnValue('x')
fn(2); // Will throw a helpful jest assertion error with args diff
Use any of mockReturnValue
, mockResolvedValue
or mockRejectedValue
directly on the object
to set up a default behavior, which will serve as fallback if no matcher fits.
when(fn)
.mockReturnValue('default')
.calledWith('foo').mockReturnValue('special')
expect(fn('foo')).toEqual('special')
expect(fn('bar')).toEqual('default')
You could use this to call callbacks passed to your mock fn or other custom functionality.
const cb = jest.fn()
when(fn).calledWith(cb).mockImplementation(callbackArg => callbackArg())
fn(cb)
expect(cb).toBeCalled()
Thanks to @idan-at.
You could use this to prevent mocks from carrying state between tests or assertions.
const { when, resetAllWhenMocks } = require('jest-when')
const fn = jest.fn()
when(fn).expectCalledWith(1).mockReturnValueOnce('x')
expect(fn(1)).toEqual('x')
resetAllWhenMocks()
when(fn).expectCalledWith(1).mockReturnValueOnce('z')
expect(fn(1)).toEqual('z')
Thanks to @whoaa512.
Call verifyAllWhenMocksCalled
after your test to assert that all mocks were used.
const { when, verifyAllWhenMocksCalled } = require('jest-when')
const fn = jest.fn()
when(fn).expectCalledWith(1).mockReturnValueOnce('x')
expect(fn(1)).toEqual('x')
verifyAllWhenMocksCalled() // passes
const { when, verifyAllWhenMocksCalled } = require('jest-when')
const fn = jest.fn()
when(fn).expectCalledWith(1).mockReturnValueOnce('x')
verifyAllWhenMocksCalled() // fails
Thanks to @roaclark.
FAQs
An extension lib for jest
The npm package jest-when receives a total of 487,961 weekly downloads. As such, jest-when popularity was classified as popular.
We found that jest-when demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.