Asymmetric equality matchers в Jasmine представляют собой мощный инструмент для проверки значений в тестах, позволяя создавать условия, которые не требуют точного совпадения ожидаемого и фактического значения, а проверяют соответствие определённым критериям. Эти матчеры особенно полезны при тестировании объектов с динамическими или частично неизвестными свойствами.
Ассиметричные матчеры — это объекты, реализующие
метод asymmetricMatch(actual), который возвращает
true, если переданное значение соответствует критериям, и
false в противном случае. Такой подход позволяет создавать
гибкие проверки, которые не зависят от полного совпадения структуры
объекта или массива.
Все ассиметричные матчеры реализуют стандартный интерфейс Jasmine и
могут использоваться в методах expect:
expect(actual).toEqual(jasmine.any(Number));
Здесь jasmine.any(Number) является ассиметричным
матчером, который проверяет, что actual является числом,
независимо от конкретного значения.
jasmine.any(constructor) Проверяет тип значения, используя конструктор. Подходит для проверки объектов, массивов и встроенных типов.
expect({name: "Alex", age: 30}).toEqual({
name: jasmine.any(String),
age: jasmine.any(Number)
});jasmine.anything() Соответствует любому
значению, кроме null и undefined.
expect(getValue()).toEqual(jasmine.anything());jasmine.objectContaining(obj) Проверяет, что объект содержит указанные свойства с соответствующими значениями. Полезно, когда объект имеет дополнительные динамические свойства.
const user = {id: 1, name: "Alice", role: "admin"};
expect(user).toEqual(jasmine.objectContaining({name: "Alice"}));jasmine.arrayContaining(array) Проверяет, что массив содержит указанные элементы, без учёта порядка и дополнительных элементов.
expect([1, 2, 3, 4]).toEqual(jasmine.arrayContaining([2, 4]));jasmine.stringMatching(pattern) Проверяет, что строка соответствует регулярному выражению или содержит указанный подстроковый паттерн.
expect("hello world").toEqual(jasmine.stringMatching(/^hello/));jasmine.objectContaining и jasmine.arrayContaining в сочетании Ассиметричные матчеры можно комбинировать для проверки сложных структур данных:
const response = {
users: [
{id: 1, name: "Alice"},
{id: 2, name: "Bob"}
],
meta: {total: 2}
};
expect(response).toEqual(jasmine.objectContaining({
users: jasmine.arrayContaining([
jasmine.objectContaining({name: "Alice"})
])
}));Можно создавать собственные матчеры, реализуя метод
asymmetricMatch. Это особенно полезно, когда требуется
проверка нестандартных условий.
class GreaterThan {
constructor(expected) {
this.expected = expected;
}
asymmetricMatch(actual) {
return actual > this.expected;
}
toString() {
return `<GreaterThan ${this.expected}>`;
}
jasmineToString() {
return this.toString();
}
}
expect(10).toEqual(new GreaterThan(5)); // true
Метод toString и jasmineToString
обеспечивают корректное отображение сообщения об ошибке при провале
теста.
Ассиметричные матчеры особенно полезны в следующих сценариях:
objectContaining,
arrayContaining), создавая вложенные проверки.toEqual и
expect(...).toEqual(...), но не с toBe, так
как toBe проверяет строгое совпадение по
ссылке.jasmine.any, а не
вручную сравнивать typeof, так как это делает тесты более
читаемыми.arrayContaining и objectContaining, чтобы
избежать тестов, зависящих от полного совпадения структуры.toString для информативного вывода ошибок.Ассиметричные матчеры в Jasmine являются фундаментальным инструментом для гибкого и мощного тестирования, позволяя сосредоточиться на логике проверки без жёсткой зависимости от полного совпадения данных. Они делают тесты более устойчивыми к изменениям структуры данных и повышают читаемость кода тестов.