При написании модульного теста, какой из них я должен предпочесть в качестве ожидаемого значения?

#java #unit-testing #testing

#java #модульное тестирование #тестирование

Вопрос:

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

Я написал модульный тест для исключения.

 // given
Company company = new Company("Comp1", 2); // constructor (company name, language)  **  2 -> EN
User user = new User("User1");
Email email = new Email("Email Test", "Test");
int emailLimit = company.getEmailLimit();
    
// when
for (int i = 0; i < emailLimit; i  ) {
     company.SendEmail(email, user);
}
Throwable throwable = catchThrowable(() -> company.SendEmail(email, user));

// then
assertThat(throwable).isInstanceOf(MessageLimitException.class);
  

Я также хочу проверить содержимое сообщения.

Существует класс с именем «ErrorMessages«, который управляет содержимым сообщения об ошибке.

 public class ErrorMessages {

   private static String[] messageLimitErrorMessage = {
        "Message Limit Error",   // 0 -> default
        "Mesaj limiti aşıldı",   // 1 -> TR
        "Message limit exceeded" // 2 -> EN
   };

   public static String messageLimitException(int languageIndex) {
        return messageLimitErrorMessage[languageIndex];
   };

}
  

Какой из них я должен предпочесть в качестве ожидаемого значения?

 // Option 1
assertThat(throwable).hasMessage(ErrorMessages.messageLimitException(company.getLanguage()));

// or

// Option 2
assertThat(throwable).hasMessage("Message limit exceeded");
  

Оба верны, но какой из них я должен предпочесть для точности теста, вариант 1 или 2?

Заранее спасибо за ваш ответ.

Комментарии:

1. Поскольку это модульный тест, я бы предпочел узкую область. Итак, мой голос будет за вариант 1. У вас должен быть отдельный тест для класса ErrorMessages, чтобы проверить, правильно ли создаются сообщения об ошибках для каждого языка.

2. Я также напишу модульный тест для класса ErrorMessages .

Ответ №1:

На этот вопрос нет однозначного ответа. Это зависит от того, чего вы пытаетесь достичь. Если точное возвращаемое сообщение об ошибке важно (например, часть спецификации), вам следует выбрать вариант 2. Если вы не хотите жестко кодировать сообщение в тесте (например, потому что оно может измениться), вы можете выбрать вариант 1.

В общем, тест должен быть сосредоточен на одной конкретной вещи, которую он пытается протестировать. Тестирование точного сообщения об ошибке может быть лучше выполнить в отдельном модульном тестировании (например, где вы могли бы протестировать все разные сообщения). Лично я обычно не утруждаю себя написанием тестов для сообщений об ошибках, если в них нет чего-то особенного (например, у них есть какая-то изменчивость в самом сообщении). У вас есть только столько времени, и, вероятно, его лучше потратить в другом месте.

Вам также следует рассмотреть возможность использования встроенной поддержки Java для интернационализированных пакетов сообщений. Он позволяет хранить сообщения, зависящие от локали, в файлах свойств и загружать их для вас.

Комментарии:

1. Спасибо за ваш ответ, вы правы. Я также напишу модульный тест для класса ErrorMessages .

Ответ №2:

«По мере того, как тесты становятся более конкретными, код становится более общим».

Написание теста с очень конкретным ожиданием отделяет его от реализации и позволяет коду со временем становиться более универсальным.

Это должно сказать вам, что вам, вероятно, следует использовать вариант 2.

Вот мнение Роберта Мартина об этом.