Java 在编写单元测试时,我应该选择哪一个作为预期值?

Java 在编写单元测试时,我应该选择哪一个作为预期值?,java,unit-testing,testing,junit,Java,Unit Testing,Testing,Junit,我正在开发一个项目。本项目的主题是公司向用户发送消息。每个公司都有一个消息限制,当超过消息限制时,系统会根据公司选择的语言引发异常 我为异常编写了单元测试 // given Company company = new Company("Comp1", 2); // constructor (company name, language) ** 2 -> EN User user = new User("User1"); Email email =

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

我为异常编写了单元测试

// 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);
我应该选择哪一个作为期望值

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

// or

// Option 2
assertThat(throwable).hasMessage("Message limit exceeded");
两者都是正确的,但是对于测试的准确性,我应该选择哪一个,选项1还是选项2

提前感谢您的回答。

“随着测试变得更加具体,代码也变得更加通用。”

使用非常特定的期望编写测试,将其与实现分离,并允许代码随着时间的推移变得更加通用

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


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

一般来说,测试应该专注于它试图测试的一件特定的事情。测试准确的错误消息最好在单独的单元测试中完成(例如,您可以测试所有不同的消息)。就我个人而言,我通常不会为错误消息编写测试,除非它们有特殊之处(例如,它们在消息本身中有某种变化)。你只有这么多时间,也许最好到别处去


你也应该考虑使用java的。它允许您在属性文件中保存特定于语言环境的消息,并为您加载这些消息。

因为它是一个单元测试,所以我更喜欢狭窄的范围。因此,我将投票支持选项1。您应该有单独的ErrorMessages类测试,以测试为每种语言创建的错误消息是否正确。我也将为ErrorMessages类编写单元测试。谢谢您的回答,您是对的。我还将为ErrorMessages类编写单元测试。
// Option 1
assertThat(throwable).hasMessage(ErrorMessages.messageLimitException(company.getLanguage()));

// or

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