Нужно ли создавать новые константы для тестов

И да, и нет. Это зависит от того, что вы тестируете.

Если константа является частью общедоступного API, ее, вероятно, следует тестировать. Но
в противном случае вы просто сделаете свои тесты более шаткими.

В каких случаях это имеет смысл

Если у вас есть

class Currency { 
    public static readonly EUROS = 'EUR'
}
Войти в полноэкранный режим Выход из полноэкранного режима

то вполне допустимо написать тест типа

test('Currency.EUROS is EUR', () => {
    expect(Currency.EUROS).toBe('EUR');
})
Войти в полноэкранный режим Выйти из полноэкранного режима

В большинстве случаев это излишество. Но если вы имеете дело с чем-то, где
строка валюты имеет большое значение, возможно, имеет смысл написать такой тест.

Где это не имеет смысла

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

class CurrencyLocaleService {
    getCurrencyForLocale(locale: string): string {
        if (locale === Locale.SPAIN) {
            return Currency.EUROS
        }
        ...
    }
}

...
describe('CurrencyLocaleService', () => {
    const SPAIN_LOCALE = 'es_ES'

    const CURRENCY_EUR = 'EUR'

    test('getCurrencyForLocale with spain locale, returns euros', () => {
        const sut = new CurrencyLocaleService();
        expect(sut.getCurrencyForLocale(SPAIN_LOCALE)).toBe(CURRENCY_EUR);
    })
})
Войти в полноэкранный режим Выйти из полноэкранного режима

Таким образом, мы неявно получаем пользу от первого теста. Если вышеприведенный тест не сработает,
это также будет означать, что Currency.EUROS была изменена.

Более того, мы также неявно проверяем корректность Locale.SPAIN, поэтому.
если она когда-нибудь изменится, этот тест также не пройдет.

Таким образом, приведенный выше тест доказывает правильность программы гораздо лучше, чем
этот:

describe('CurrencyLocaleService', () => {
    test('getCurrencyForLocale with spain locale, returns euros', () => {
        const sut = new CurrencyLocaleService();
        expect(sut.getCurrencyForLocale(Locale.SPAIN)).toBe(Currency.EUROS);
    })
})
Вход в полноэкранный режим Выйти из полноэкранного режима

Однако этот тест мне нравится больше, потому что он проверяет только одну вещь. У нас может быть
законная причина для изменения значений этих констант, может быть, какой-то внешний
API требует, чтобы валюта была в нижнем регистре 'eur'. Если это так, то тест
который проверяет, что getCurrencyForLocale с локалью spain, возвращает евро, не должен провалиться, потому что, хотя строка изменилась.
потому что, хотя строка изменилась, Currency.EUROS по-прежнему означает то же самое.

Возможно, нам придется изменить наш первый тест следующим образом

test('Currency.EUROS is eur', () => {
    expect(Currency.EUROS).toBe('eur');
})
Войти в полноэкранный режим Выйти из полноэкранного режима

Но не оба теста.

Тесты на самом деле не доказывают правильность вашего кода.

Я думаю, что людям нравится писать тесты, подобные этому

describe('CurrencyLocaleService', () => {
    const SPAIN_LOCALE = 'es_ES'

    const CURRENCY_EUR = 'EUR'

    test('getCurrencyForLocale with spain locale, returns euros', () => {
        const sut = new CurrencyLocaleService();
        expect(sut.getCurrencyForLocale(SPAIN_LOCALE)).toBe(CURRENCY_EUR);
    })
})
Войти в полноэкранный режим Выйти из полноэкранного режима

заключается в убеждении, что цель наших тестов — показать корректность и защитить
код от того, чтобы он стал неправильным. Если кто-то придет и изменит значение
Currency.EURO, все наши тесты будут провалены, и нет никаких шансов, что код
попадет в производство.

Однако нам придется изменить код, и это не означает, что код стал
неправильный.

Тесты на самом деле не показывают, что ваш код правильный, я так не думаю. Они
выражают то, что мы ожидаем от нашего кода. Если я внесу изменения в существующий
код, тесты должны не сработать, но только в той степени, в которой изменились наши ожидания.

Если я изменю Locale.SPAIN с 'es_ES' на 'es-ES', этот тест должен завершиться неудачно.

test('Locale.SPAIN is "es_ES"', () => {
    expect(Locale.SPAIN).toBe('es-ES');
})
Войдите в полноэкранный режим выйти из полноэкранного режима

если он существует, потому что ожидание изменилось. Но ни один другой тест не должен завершиться неудачей.

Оригинальная статья: https://www.ethancarlsson.dev/blog/constantsintests

Оцените статью
devanswers.ru
Добавить комментарий