Mock Matchers
Mock matchers help you test the behavior of mock functions by verifying they were called with specific arguments, returned expected values, and more.
toHaveBeenCalled
Verifies that a mock function has been called at least once.
expect(mockFn).toHaveBeenCalled()
Examples
// Creating a mock function
const mockFn = xJet.fn()
// After calling the mock
mockFn()
expect(mockFn).toHaveBeenCalled() // Passes
// When the mock hasn't been called
const unusedMock = xJet.fn()
expect(unusedMock).not.toHaveBeenCalled() // Passes
toHaveBeenCalledTimes
Verifies that a mock function has been called an exact number of times.
expect(mockFn).toHaveBeenCalledTimes(expectedCount)
Parameters
expectedCount
: The exact number of times the mock should have been called
Examples
const mockFn = xJet.fn()
// No calls
expect(mockFn).toHaveBeenCalledTimes(0) // Passes
// After multiple calls
mockFn()
mockFn()
mockFn()
expect(mockFn).toHaveBeenCalledTimes(3) // Passes
expect(mockFn).not.toHaveBeenCalledTimes(2) // Passes
toHaveBeenCalledWith
Verifies that a mock function has been called with specified arguments at least once.
expect(mockFn).toHaveBeenCalledWith(...expectedArgs)
INFO
🚀 Supports asymmetric matchers
Parameters
...expectedArgs
: The expected arguments that the mock function should have been called with
Examples
const mockFn = xJet.fn()
// Basic usage
mockFn('hello', 123)
expect(mockFn).toHaveBeenCalledWith('hello', 123) // Passes
// Multiple calls with different arguments
mockFn('first call')
mockFn('second call')
expect(mockFn).toHaveBeenCalledWith('first call') // Passes
expect(mockFn).toHaveBeenCalledWith('second call') // Passes
expect(mockFn).not.toHaveBeenCalledWith('never called') // Passes
// With objects
mockFn({ name: 'John', age: 30 })
expect(mockFn).toHaveBeenCalledWith({ name: 'John', age: 30 }) // Passes
// With asymmetric matchers
mockFn('hello world', { id: 123, data: [1, 2, 3] })
expect(mockFn).toHaveBeenCalledWith(
expect.stringContaining('hello'),
expect.objectContaining({ id: 123 })
) // Passes
toHaveBeenLastCalledWith
Verifies that the last call to a mock function was with specified arguments.
expect(mockFn).toHaveBeenLastCalledWith(...expectedArgs)
INFO
🚀 Supports asymmetric matchers
Parameters
...expectedArgs
: The expected arguments of the last call to the mock function
Examples
const mockFn = xJet.fn()
// Multiple calls with different arguments
mockFn('first call')
mockFn('second call')
mockFn('last call')
expect(mockFn).toHaveBeenLastCalledWith('last call') // Passes
expect(mockFn).not.toHaveBeenLastCalledWith('first call') // Passes
// With asymmetric matchers
mockFn({ type: 'final', id: 42 })
expect(mockFn).toHaveBeenLastCalledWith(
expect.objectContaining({ type: 'final' })
) // Passes
toHaveBeenNthCalledWith
Verifies that the nth call to a mock function was with specified arguments.
expect(mockFn).toHaveBeenNthCalledWith(n, ...expectedArgs)
INFO
🚀 Supports asymmetric matchers
Parameters
n
: The call number to check (1-based index)...expectedArgs
: The expected arguments of the nth call
Examples
const mockFn = xJet.fn()
// Series of calls with different arguments
mockFn('first')
mockFn('second')
mockFn('third')
expect(mockFn).toHaveBeenNthCalledWith(1, 'first') // Passes
expect(mockFn).toHaveBeenNthCalledWith(2, 'second') // Passes
expect(mockFn).toHaveBeenNthCalledWith(3, 'third') // Passes
expect(mockFn).not.toHaveBeenNthCalledWith(2, 'first') // Passes
// With complex arguments and asymmetric matchers
mockFn(1, { a: 'one' })
mockFn(2, { a: 'two' })
expect(mockFn).toHaveBeenNthCalledWith(
5,
2,
expect.objectContaining({ a: 'two' })
) // Passes
toHaveReturned
Verifies that a mock function successfully returned at least once (did not throw).
expect(mockFn).toHaveReturned()
Examples
// Mock that returns normally
const successMock = xJet.fn(() => true)
successMock()
expect(successMock).toHaveReturned() // Passes
// Mock that throws
const failMock = xJet.fn(() => { throw new Error('Failed') })
try {
failMock()
} catch (e) {
// Ignore error
}
expect(failMock).not.toHaveReturned() // Passes
// Mixed behavior
const mixedMock = xJet.fn(x => {
if (x < 0) throw new Error('Negative')
return x * 2
})
try { mixedMock(-1) } catch (e) { /* Ignore */ }
mixedMock(5)
expect(mixedMock).toHaveReturned() // Passes - returned at least once
toHaveReturnedTimes
Verifies that a mock function successfully returned exactly n times.
expect(mockFn).toHaveReturnedTimes(expectedCount)
Parameters
expectedCount
: The exact number of times the mock should have returned
Examples
const mockFn = xJet.fn(x => x * 2)
mockFn(1)
mockFn(2)
mockFn(3)
expect(mockFn).toHaveReturnedTimes(3) // Passes
// With some errors
const mixedMock = xJet.fn(x => {
if (x < 0) throw new Error('Negative')
return x * 2
})
mixedMock(1)
try { mixedMock(-1) } catch (e) { /* Ignore */ }
mixedMock(2)
expect(mixedMock).toHaveReturnedTimes(2) // Passes - only counts successful returns
toHaveLastReturnedWith
Verifies that the last return value of a mock function matches the expected value.
expect(mockFn).toHaveLastReturnedWith(expectedValue)
INFO
🚀 Supports asymmetric matchers
Parameters
expectedValue
: The value that should match the last return of the mock function
Examples
const mockFn = xJet.fn()
mockFn.mockReturnValueOnce('first result')
mockFn.mockReturnValueOnce('second result')
mockFn.mockReturnValue('default result')
mockFn() // Returns 'first result'
mockFn() // Returns 'second result'
mockFn() // Returns 'default result'
expect(mockFn).toHaveLastReturnedWith('default result') // Passes
expect(mockFn).not.toHaveLastReturnedWith('second result') // Passes
// With asymmetric matchers
const dataMock = xJet.fn().mockReturnValue({ id: 42, timestamp: Date.now() })
dataMock()
expect(dataMock).toHaveLastReturnedWith(
expect.objectContaining({ id: 42 })
) // Passes
toHaveNthReturnedWith
Verifies that the nth return value of a mock function matches the expected value.
expect(mockFn).toHaveNthReturnedWith(n, expectedValue)
INFO
🚀 Supports asymmetric matchers
Parameters
n
: The call number to check (1-based index)expectedValue
: The value that should match the nth return of the mock function
Examples
const mockFn = xJet.fn()
.mockReturnValueOnce('first')
.mockReturnValueOnce('second')
.mockReturnValueOnce('third')
mockFn() // Returns 'first'
mockFn() // Returns 'second'
mockFn() // Returns 'third'
expect(mockFn).toHaveNthReturnedWith(1, 'first') // Passes
expect(mockFn).toHaveNthReturnedWith(2, 'second') // Passes
expect(mockFn).toHaveNthReturnedWith(3, 'third') // Passes
expect(mockFn).not.toHaveNthReturnedWith(2, 'third') // Passes
// With asymmetric matchers
const complexMock = xJet.fn()
.mockReturnValueOnce({ type: 'user', data: { id: 1 } })
.mockReturnValueOnce({ type: 'post', data: { id: 2 } })
complexMock()
complexMock()
expect(complexMock).toHaveNthReturnedWith(
1,
expect.objectContaining({ type: 'user' })
) // Passes
Common Testing Patterns
Testing Callback Arguments
test('callback is called with correct arguments', () => {
const mockCallback = xJet.fn()
// Function that accepts a callback
function processData(data, callback) {
// Do something with data
callback(data.id, data.value)
}
processData({ id: 123, value: 'test' }, mockCallback)
expect(mockCallback).toHaveBeenCalledWith(123, 'test')
})
Testing API Requests
test('API endpoint is called with correct parameters', async () => {
// Mock the fetch function
global.fetch = xJet.fn().mockResolvedValue({
ok: true,
json: async () => ({ success: true })
})
// Function that makes API call
await fetchUserData(42, 'full')
// Verify the API was called correctly
expect(fetch).toHaveBeenCalledWith(
'https://api.example.com/users/42?profile=full',
expect.objectContaining({
method: 'GET',
headers: expect.objectContaining({
'Content-Type': 'application/json'
})
})
)
})
Testing Call Order
test('operations are performed in the correct sequence', () => {
const logger = xJet.fn()
function performOperations() {
logger('Starting')
// Do something
logger('Processing')
// Do something else
logger('Completed')
}
performOperations()
expect(logger).toHaveBeenNthCalledWith(1, 'Starting')
expect(logger).toHaveBeenNthCalledWith(2, 'Processing')
expect(logger).toHaveBeenNthCalledWith(3, 'Completed')
expect(logger).toHaveBeenCalledTimes(3)
})
Testing Conditional Logic
test('conditional function calls', () => {
const mockFn = xJet.fn()
function processValue(value) {
if (value > 0) {
mockFn(`Positive: ${value}`)
} else if (value < 0) {
mockFn(`Negative: ${value}`)
} else {
mockFn('Zero')
}
}
processValue(5)
processValue(-3)
processValue(0)
expect(mockFn).toHaveBeenCalledWith('Positive: 5')
expect(mockFn).toHaveBeenCalledWith('Negative: -3')
expect(mockFn).toHaveBeenCalledWith('Zero')
expect(mockFn).toHaveBeenCalledTimes(3)
})
Testing Return Values
test('function returns expected values', () => {
const transformData = xJet.fn()
.mockReturnValueOnce({ transformed: true, id: 1 })
.mockReturnValueOnce({ transformed: true, id: 2 })
const result1 = transformData({ id: 1 })
const result2 = transformData({ id: 2 })
expect(transformData).toHaveNthReturnedWith(1, { transformed: true, id: 1 })
expect(transformData).toHaveLastReturnedWith({ transformed: true, id: 2 })
expect(transformData).toHaveReturnedTimes(2)
})
Testing Event Handlers
test('event handlers are called correctly', () => {
// Mock event handlers
const onSuccess = xJet.fn()
const onError = xJet.fn()
const onComplete = xJet.fn()
// Function with event handlers
function processWithEvents(data, options) {
try {
// Processing
if (data.valid) {
onSuccess(data.result)
} else {
onError(new Error('Invalid data'))
}
} finally {
onComplete()
}
}
// Test success path
processWithEvents({ valid: true, result: 'success' })
expect(onSuccess).toHaveBeenCalledWith('success')
expect(onError).not.toHaveBeenCalled()
expect(onComplete).toHaveBeenCalled()
// Reset mocks
xJet.clearAllMocks()
// Test error path
processWithEvents({ valid: false })
expect(onSuccess).not.toHaveBeenCalled()
expect(onError).toHaveBeenCalledWith(expect.any(Error))
expect(onComplete).toHaveBeenCalled()
})