Использование should

Mocha предоставляет разработчикам мощный инструмент для написания тестов в JavaScript. Одним из ключевых аспектов работы с Mocha является использование различных утверждений, и одним из наиболее популярных является should. В рамках тестирования он позволяет создавать более читаемые и выразительные тесты, поддерживающие естественную человеческую форму языка.

Что такое should?

should — это библиотека утверждений для JavaScript, которая предоставляет синтаксис для написания тестов в стиле, приближенном к естественному языку. Это означает, что вместо использования обычных методов утверждений, таких как assert.equal() или assert.deepEqual(), разработчик может использовать более интуитивно понятный синтаксис: someValue.should.equal(expectedValue).

Чтобы начать использовать should, необходимо подключить эту библиотеку. В Mocha should интегрируется прямо в тесты, предоставляя множество полезных методов для различных типов проверок. Обычно для этого используют модуль chai, который включает в себя should как один из вариантов утверждений.

const chai = require('chai');
chai.should();

После подключения этой библиотеки, should становится доступным для всех тестируемых объектов в рамках теста, что делает код более читаемым.

Структура и использование should

Основной синтаксис использования should состоит из следующего паттерна: объект, после которого идет метод утверждения. Пример:

const result = add(2, 3);
result.should.equal(5);

В данном примере проверяется, что результат выполнения функции add(2, 3) должен быть равен 5. Суть утверждения заключается в том, что метод should.equal() будет проверять, соответствует ли фактическое значение ожидаемому. Если нет — тест завершится с ошибкой.

Популярные методы утверждений с should
  1. should.equal() Проверка на равенство значений. Сравниваются два значения на строгое равенство (по значению и типу).

    const result = 10;
    result.should.equal(10);  // Пройдет
    result.should.equal('10');  // Ошибка
  2. should.not.equal() Проверка на неравенство значений.

    const result = 10;
    result.should.not.equal(5);  // Пройдет
    result.should.not.equal(10); // Ошибка
  3. should.deepEqual() Сравнение объектов и массивов на «глубокое» равенство, при котором проверяются все вложенные свойства.

    const obj1 = { name: 'John', age: 30 };
    const obj2 = { name: 'John', age: 30 };
    obj1.should.deepEqual(obj2);  // Пройдет
  4. should.not.deepEqual() Проверка на неравенство объектов и массивов по всем вложенным значениям.

    const obj1 = { name: 'John', age: 30 };
    const obj2 = { name: 'John', age: 31 };
    obj1.should.not.deepEqual(obj2);  // Пройдет
  5. should.be.true / should.be.false Проверка на истинность или ложность значений.

    const result = true;
    result.should.be.true;  // Пройдет
    result.should.be.false; // Ошибка
  6. should.exist Проверка существования значения (не null и не undefined).

    const result = 'hello';
    result.should.exist;  // Пройдет
  7. should.be.null Проверка на null.

    const result = null;
    result.should.be.null;  // Пройдет
  8. should.be.undefined Проверка на undefined.

    let result;
    result.should.be.undefined;  // Пройдет
  9. should.be.a() / should.be.an() Проверка типа объекта (можно использовать для проверки типа массива, строки, числа и других объектов).

    const result = [1, 2, 3];
    result.should.be.an('array');  // Пройдет
    result.should.be.a('string');  // Ошибка
  10. should.have.property() Проверка наличия свойства у объекта.

    const obj = { name: 'John', age: 30 };
    obj.should.have.property('name');  // Пройдет
    obj.should.have.property('address');  // Ошибка
  11. should.throw() Проверка на выбрасывание исключений. Может быть использована для проверки того, что определенный код вызывает ошибку.

    (function() {
      throw new Error('Test error');
    }).should.throw(Error);  // Пройдет

Сравнение с другими библиотеками утверждений

should является частью библиотеки chai, которая также включает два других популярных стиля утверждений: expect и assert. Каждый стиль имеет свои особенности и предпочтения.

  • expect: Синтаксис ориентирован на утверждения в стиле “ожидания”. Например:

    expect(result).to.equal(5);
  • assert: Использует традиционные утверждения, которые возвращают истинное или ложное значение. Например:

    assert.equal(result, 5);

should отличается от этих стилей тем, что он позволяет писать код, максимально приближенный к естественному языку, что делает тесты более легкими для восприятия.

Стандарты и соглашения

Для использования should в проекте необходимо установить соответствующие пакеты. Обычно устанавливаются chai и сам should:

npm install chai --save-dev

Затем в тестах подключается chai и вызывается метод should(), чтобы добавить поддержку синтаксиса should.

При работе с should важно помнить, что он изменяет прототипы объектов JavaScript, добавляя в них методы для утверждений. Это позволяет тестировать не только примитивные значения, но и объекты, массивы, функции и другие типы данных.

Также следует соблюдать осторожность при использовании should с асинхронными тестами, так как should может не всегда работать с промисами и асинхронными функциями так, как хотелось бы. Для асинхронных тестов часто используют done() или async/await.

Пример теста с использованием should

describe('Тестирование функции', function() {
  it('должен возвращать правильный результат', function() {
    const result = add(2, 3);
    result.should.equal(5);
  });

  it('должен выбрасывать ошибку при неверных данных', function() {
    (function() {
      add(2, 'a');
    }).should.throw(Error);
  });
});

В этом примере выполняется два теста: один проверяет, что функция возвращает правильный результат, другой — что функция выбрасывает ошибку при некорректных входных данных.

Заключение

Использование should делает тесты в Mocha более выразительными и читаемыми, приближая их к естественному языку. Благодаря множеству удобных методов, таких как should.equal(), should.exist, should.throw(), можно легко проверять различные аспекты работы функций и объектов. Однако следует учитывать, что синтаксис should может не подходить для всех типов тестов, особенно в случае асинхронных операций или сложных случаев с промисами.