И да, и нет. Это зависит от того, что вы тестируете.
Если константа является частью общедоступного 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