A comprehensive matcher library for Jest testing framework providing assertion utilities for test expectations
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Special matchers for flexible pattern matching and partial object comparison. These matchers allow for more flexible assertions when exact matching is not practical or desired.
Matches any value except null and undefined.
/**
* Matches anything except null or undefined
* @returns Anything matcher instance
*/
expect.anything(): Anything;Usage Examples:
// Use in arrays
expect(['alice', 'bob', 'charlie']).toEqual([
'alice',
expect.anything(),
'charlie'
]);
// Use in objects
expect({
name: 'John',
id: 123,
timestamp: new Date()
}).toEqual({
name: 'John',
id: expect.anything(),
timestamp: expect.anything()
});
// Use with function calls
const mockFn = jest.fn();
mockFn('hello', 42, true);
expect(mockFn).toHaveBeenCalledWith(
'hello',
expect.anything(),
expect.anything()
);
// Won't match null or undefined
expect({value: null}).not.toEqual({value: expect.anything()});
expect({value: undefined}).not.toEqual({value: expect.anything()});Matches any instance of the specified constructor or type.
/**
* Matches any instance of given constructor
* @param constructor - Constructor function or class to match against
* @returns Any matcher instance
*/
expect.any(constructor: Function): Any;Usage Examples:
// Primitive types
expect('hello').toEqual(expect.any(String));
expect(42).toEqual(expect.any(Number));
expect(true).toEqual(expect.any(Boolean));
// Object types
expect(new Date()).toEqual(expect.any(Date));
expect([1, 2, 3]).toEqual(expect.any(Array));
expect(/regex/).toEqual(expect.any(RegExp));
expect(new Error('test')).toEqual(expect.any(Error));
// Custom classes
class User {
constructor(name) {
this.name = name;
}
}
const user = new User('John');
expect(user).toEqual(expect.any(User));
// Use in complex objects
expect({
user: new User('John'),
createdAt: new Date(),
tags: ['admin', 'active']
}).toEqual({
user: expect.any(User),
createdAt: expect.any(Date),
tags: expect.any(Array)
});
// Use with mock function verification
const mockCallback = jest.fn();
mockCallback(new Error('something failed'));
expect(mockCallback).toHaveBeenCalledWith(expect.any(Error));Matches objects that contain the specified properties (subset matching).
/**
* Matches objects containing provided properties
* @param object - Object with properties that should be present
* @returns ObjectContaining matcher instance
*/
expect.objectContaining(object: Object): ObjectContaining;Usage Examples:
// Basic object containment
const user = {
id: 1,
name: 'John',
email: 'john@example.com',
preferences: {theme: 'dark'},
roles: ['user', 'admin']
};
expect(user).toEqual(expect.objectContaining({
name: 'John',
email: 'john@example.com'
}));
// Nested object containment
expect(user).toEqual(expect.objectContaining({
preferences: expect.objectContaining({
theme: 'dark'
})
}));
// Use in arrays
expect([
{id: 1, name: 'John'},
{id: 2, name: 'Jane'},
{id: 3, name: 'Bob'}
]).toContainEqual(expect.objectContaining({name: 'Jane'}));
// API response testing
const apiResponse = {
data: {id: 123, name: 'John'},
metadata: {timestamp: '2023-01-01', version: '1.0'},
status: 'success'
};
expect(apiResponse).toEqual(expect.objectContaining({
data: expect.objectContaining({id: 123}),
status: 'success'
}));
// Mock function verification
const mockFn = jest.fn();
mockFn({name: 'John', age: 30, city: 'New York'});
expect(mockFn).toHaveBeenCalledWith(
expect.objectContaining({name: 'John', age: 30})
);Matches arrays that contain all of the specified elements.
/**
* Matches arrays containing all provided elements
* @param array - Array with elements that should be present
* @returns ArrayContaining matcher instance
*/
expect.arrayContaining(array: Array): ArrayContaining;Usage Examples:
// Basic array containment
expect(['a', 'b', 'c', 'd', 'e']).toEqual(
expect.arrayContaining(['a', 'c', 'e'])
);
// Order doesn't matter
expect(['z', 'y', 'x']).toEqual(
expect.arrayContaining(['x', 'z'])
);
// Works with objects
expect([
{name: 'Alice', age: 25},
{name: 'Bob', age: 30},
{name: 'Charlie', age: 35}
]).toEqual(expect.arrayContaining([
{name: 'Alice', age: 25},
{name: 'Charlie', age: 35}
]));
// Nested in objects
expect({
users: ['john', 'jane', 'bob'],
admins: ['alice', 'charlie']
}).toEqual({
users: expect.arrayContaining(['john', 'jane']),
admins: expect.arrayContaining(['alice'])
});
// Testing API responses
const searchResults = {
results: [
{id: 1, title: 'First Post'},
{id: 2, title: 'Second Post'},
{id: 3, title: 'Third Post'}
]
};
expect(searchResults).toEqual({
results: expect.arrayContaining([
expect.objectContaining({title: 'First Post'}),
expect.objectContaining({title: 'Third Post'})
])
});Matches strings that contain the specified substring.
/**
* Matches strings containing provided substring
* @param string - Substring that should be present
* @returns StringContaining matcher instance
*/
expect.stringContaining(string: string): StringContaining;Usage Examples:
// Basic substring matching
expect('Hello World').toEqual(expect.stringContaining('World'));
expect('JavaScript is awesome').toEqual(expect.stringContaining('Script'));
// Case sensitive
expect('Hello World').toEqual(expect.stringContaining('World'));
expect('Hello World').not.toEqual(expect.stringContaining('world'));
// Use in objects
expect({
message: 'User registration successful',
details: 'Account created for user@example.com'
}).toEqual({
message: expect.stringContaining('successful'),
details: expect.stringContaining('user@example.com')
});
// Use in arrays
expect(['error: file not found', 'warning: deprecated method']).toEqual([
expect.stringContaining('error:'),
expect.stringContaining('warning:')
]);
// Testing log messages
const logMessages = [
'INFO: Application started',
'DEBUG: Database connected',
'ERROR: Failed to process request'
];
expect(logMessages).toEqual(expect.arrayContaining([
expect.stringContaining('Application started'),
expect.stringContaining('ERROR:')
]));Matches strings that match the specified regular expression pattern.
/**
* Matches strings matching provided pattern or regex
* @param pattern - String pattern or RegExp to match against
* @returns StringMatching matcher instance
*/
expect.stringMatching(pattern: string | RegExp): StringMatching;Usage Examples:
// Basic regex matching
expect('hello@example.com').toEqual(
expect.stringMatching(/^[\w\.-]+@[\w\.-]+\.\w+$/)
);
expect('2023-12-25').toEqual(
expect.stringMatching(/^\d{4}-\d{2}-\d{2}$/)
);
// String pattern matching
expect('user123').toEqual(expect.stringMatching('user'));
// Case insensitive matching
expect('JavaScript').toEqual(expect.stringMatching(/javascript/i));
// Use in complex objects
expect({
user: {
email: 'john.doe@company.com',
phone: '(555) 123-4567',
id: 'user_abc123'
}
}).toEqual({
user: {
email: expect.stringMatching(/@company\.com$/),
phone: expect.stringMatching(/^\(\d{3}\) \d{3}-\d{4}$/),
id: expect.stringMatching(/^user_/)
}
});
// Testing URL patterns
const apiUrls = [
'https://api.example.com/v1/users',
'https://api.example.com/v1/posts',
'https://api.example.com/v2/comments'
];
expect(apiUrls).toEqual(expect.arrayContaining([
expect.stringMatching(/\/v1\/users$/),
expect.stringMatching(/\/v2\//)
]));// Complex nested matching
const complexObject = {
user: {
id: 'user_123',
profile: {
name: 'John Doe',
email: 'john@example.com',
settings: {
notifications: true,
preferences: ['email', 'sms']
}
}
},
metadata: {
createdAt: new Date(),
version: '1.2.3'
}
};
expect(complexObject).toEqual({
user: expect.objectContaining({
id: expect.stringMatching(/^user_/),
profile: expect.objectContaining({
name: expect.any(String),
email: expect.stringContaining('@'),
settings: expect.objectContaining({
preferences: expect.arrayContaining(['email'])
})
})
}),
metadata: expect.objectContaining({
createdAt: expect.any(Date),
version: expect.stringMatching(/^\d+\.\d+\.\d+$/)
})
});// Testing flexible API response structure
const apiResponse = {
data: [
{id: 1, name: 'John', email: 'john@test.com', createdAt: '2023-01-01T00:00:00Z'},
{id: 2, name: 'Jane', email: 'jane@test.com', createdAt: '2023-01-02T00:00:00Z'}
],
pagination: {
total: 2,
page: 1,
perPage: 10
},
meta: {
requestId: 'req_abc123',
timestamp: 1672531200000
}
};
expect(apiResponse).toEqual({
data: expect.arrayContaining([
expect.objectContaining({
id: expect.any(Number),
name: expect.any(String),
email: expect.stringMatching(/@test\.com$/),
createdAt: expect.stringMatching(/^\d{4}-\d{2}-\d{2}T/)
})
]),
pagination: expect.objectContaining({
total: expect.any(Number),
page: 1
}),
meta: expect.objectContaining({
requestId: expect.stringMatching(/^req_/),
timestamp: expect.any(Number)
})
});// Testing event payloads with flexible structure
function trackEvent(eventName, properties) {
// Event tracking implementation
}
const trackEventSpy = jest.fn();
trackEventSpy('user_signup', {
userId: 'user_123',
email: 'user@example.com',
timestamp: Date.now(),
source: 'web',
properties: {
plan: 'premium',
referrer: 'google'
}
});
expect(trackEventSpy).toHaveBeenCalledWith(
'user_signup',
expect.objectContaining({
userId: expect.stringMatching(/^user_/),
email: expect.stringContaining('@'),
timestamp: expect.any(Number),
source: expect.any(String),
properties: expect.objectContaining({
plan: expect.any(String)
})
})
);Asymmetric matchers can be combined with regular matchers:
const mockFn = jest.fn();
mockFn('hello', {id: 123, name: 'John'}, ['a', 'b', 'c']);
expect(mockFn).toHaveBeenCalledWith(
'hello', // exact match
expect.objectContaining({id: 123}), // asymmetric match
expect.arrayContaining(['a', 'c']) // asymmetric match
);Asymmetric matchers support negation:
expect('hello').not.toEqual(expect.stringContaining('world'));
expect([1, 2, 3]).not.toEqual(expect.arrayContaining([4, 5]));
expect({a: 1}).not.toEqual(expect.objectContaining({b: 2}));