在编写单元测试时,我应该更喜欢哪一个作为期望值



我正在开发一个项目。该项目的主题是,公司向用户发送消息。每个公司都有一个消息限制,当超过消息限制时,系统会根据公司选择的语言抛出异常。

我为异常编写了单元测试。

// 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);

我还想查看消息内容。

存在一个名为"的类错误消息";其管理错误消息的内容。

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?

谢谢你提前回答。

这个问题没有明确的答案。这取决于你想要实现什么。如果返回的确切错误消息很重要(例如规范的一部分(,则应选择选项2。如果您不想将消息硬编码到测试中(例如,因为它可能会更改(,则可以选择选项1。

一般来说,测试应该专注于它试图测试的一件特定的事情。测试确切的错误消息最好在单独的单元测试中完成(例如,您可以测试所有不同的消息(。就我个人而言,我通常不会为错误消息编写测试,除非它们有什么特别之处(例如,它们在消息本身中有某种可变性(。你只有那么多的时间,最好把它花在其他地方。

您还应该考虑使用Java对国际化消息包的内置支持。它允许您在属性文件中保存特定于Locale的消息,并为您加载它们。

"随着测试变得更加具体,代码变得更加通用">

编写带有非常具体期望的测试,将其与实现解耦,并允许代码随着时间的推移变得更加通用。

这应该告诉您,您可能应该使用选项2。

这是罗伯特·马丁对它的看法。

最新更新