Java JUnit'的替代方案是什么;s assertEquals()方法,以便在测试报告中查看哪些对象字段在比较中有所不同?
我在JUnit上有很多用Java编写的自动化测试,我经常使用Java JUnit'的替代方案是什么;s assertEquals()方法,以便在测试报告中查看哪些对象字段在比较中有所不同?,java,junit,Java,Junit,我在JUnit上有很多用Java编写的自动化测试,我经常使用assertEquals(Java.lang.String消息,Java.lang.Object预期,Java.lang.Object实际)。 如果比较基元类型,则在断言失败的情况下,测试报告中可以清楚地看到值不同,例如在比较2个整数的情况下。但是,当您比较两个复杂对象时,测试的输出可能会非常混乱。即使您正确地重写了将列出所有字段和所有值的toString()方法,输出也会很长。想象一下有一节课: public class Invoic
assertEquals(Java.lang.String消息,Java.lang.Object预期,Java.lang.Object实际)
。
如果比较基元类型,则在断言失败的情况下,测试报告中可以清楚地看到值不同,例如在比较2个整数的情况下。但是,当您比较两个复杂对象时,测试的输出可能会非常混乱。即使您正确地重写了将列出所有字段和所有值的toString()
方法,输出也会很长。想象一下有一节课:
public class Invoice {
private LocalDate invoiceDate;
private String invoiceNumber;
private InvoiceType invoiceType;
private InvoiceStatus invoiceStatus;
private String mediaPlanner;
private String yourReference;
private String responsiblePerson;
private Brand advertiser;
private MediaAgency mediaAgency;
private Set<InvoiceRow> invoiceRows;
.....
公共类发票{
私有LocalDate发票日期;
私有字符串发票号码;
私有发票类型发票类型;
私有发票状态发票状态;
私有字符串mediaPlanner;
私有字符串引用;
私人串负责人;
自有品牌广告商;
私人中介机构;
私有集合发票行;
.....
InvoiceRow
也是一个非常复杂的对象,它有许多自己的字段实现和断言失败后,JUnit将输出一条很长的消息,这条消息不太容易被人看到,例如,在一个对象中,发票类型是不正确的
是否有一些工具/方法可以改进这一点,以便在比较失败的情况下,我的测试报告将显示一个相当清晰和简洁的输出?
也许我应该使用其他一些具有更多工具/功能的测试框架?“assertEquals”不知道哪个属性导致不相等的结果。JUnit只调用对象的“equals”并检查布尔结果
如果你想知道哪个属性是不同的,你需要逐个比较属性
或者,您可以实现适当的“toString”方法并比较字符串,这样您就可以看到不同的对象。“assertEquals”不知道哪个属性导致不相等的结果。JUnit只调用对象的“equals”并检查布尔结果
如果你想知道哪个属性是不同的,你需要逐个比较属性
或者您可以实现适当的“toString”方法并比较字符串,这样您就可以看到不同的对象。实现您自己的断言方法
import static org.junit.Assert.assertEquals;
...
public static void assertEquals(Invoice expected, Invoice actual) {
assertEquals("invoiceDate", expected.invoiceDate, actual.invoiceDate);
assertEquals("netPrice", expected.netPrice, actual.netPrice);
assertEquals("invoiceRows", expected.invoiceRows, actual.invoiceRows);
// and so on...
}
实现您自己的断言方法
import static org.junit.Assert.assertEquals;
...
public static void assertEquals(Invoice expected, Invoice actual) {
assertEquals("invoiceDate", expected.invoiceDate, actual.invoiceDate);
assertEquals("netPrice", expected.netPrice, actual.netPrice);
assertEquals("invoiceRows", expected.invoiceRows, actual.invoiceRows);
// and so on...
}
您可能想看看。特别是:
- 资产(预期)。isEqualToComparingFieldByField(其他)
- 断言(预期)。IsqualToComparingFieldByFieldRecursive(其他)相等
- 资产(预期)。与其他“油田1”相比,其质量相当
- 资产(预期)。IseQualIgnoringNullFields(其他)
@Test
public void assertJTest() {
Invoice expected = new Invoice();
Invoice other = new Invoice();
expected.setInvoiceNumber("123");
other.setInvoiceNumber("456");
expected.setNestedSet(singleton("12345"));
other.setNestedSet(singleton("12346"));
assertThat(expected).isEqualToIgnoringNullFields(other);
}
输出:
java.lang.AssertionError:
Expecting values:
<["123", ["12346"]]>
in fields:
<["invoiceNumber", "nestedSet"]>
but were:
<["456", ["12345"]]>
in <Invoice(nestedSet=[12345], invoiceNumber=123)>.
Comparison was performed on all fields
java.lang.AssertionError:
期望值:
在以下领域:
但是:
在里面
对所有字段进行比较
您可能想看看。尤其是:
- 资产(预期)。isEqualToComparingFieldByField(其他)
- 断言(预期)。IsqualToComparingFieldByFieldRecursive(其他)相等
- 资产(预期)。与其他“油田1”相比,其质量相当
- 资产(预期)。IseQualIgnoringNullFields(其他)
@Test
public void assertJTest() {
Invoice expected = new Invoice();
Invoice other = new Invoice();
expected.setInvoiceNumber("123");
other.setInvoiceNumber("456");
expected.setNestedSet(singleton("12345"));
other.setNestedSet(singleton("12346"));
assertThat(expected).isEqualToIgnoringNullFields(other);
}
输出:
java.lang.AssertionError:
Expecting values:
<["123", ["12346"]]>
in fields:
<["invoiceNumber", "nestedSet"]>
but were:
<["456", ["12345"]]>
in <Invoice(nestedSet=[12345], invoiceNumber=123)>.
Comparison was performed on all fields
java.lang.AssertionError:
期望值:
在以下领域:
但是:
在里面
对所有字段进行比较
Assert.assertEquals()
将调用.equals()
方法。最好的解决方案是使用自己的方法:
public class Invoice {
...
@Override
public boolean equals(Object o) {
Invoice that = (Invoice) o;
int errors = 0;
// compare each field one at a time
if(!this.invoiceDate.equals(that.invoiceDate) {
log.error(String.format("invoiceDate are not equal: expected %s, actual %s!", this.invoiceDate, that.invoiceDate)
errors++;
}
// you also have the option to do something fancy, like ignore null fields:
if(this.invoiceNumber != null && that.invoiceNumber != null) {
if(!this.invoiceNumber.equals(that.invoiceNumber) {
log.error(String.format("invoiceNumber are not equal: expected %s, actual %s!", this.invoiceDate, that.invoiceDate)
errors++;
}
}
// continue with all other fields ...
return errors == 0;
}
}
Assert.assertEquals()
将调用.equals()
方法。最好的解决方案是使用自己的方法:
public class Invoice {
...
@Override
public boolean equals(Object o) {
Invoice that = (Invoice) o;
int errors = 0;
// compare each field one at a time
if(!this.invoiceDate.equals(that.invoiceDate) {
log.error(String.format("invoiceDate are not equal: expected %s, actual %s!", this.invoiceDate, that.invoiceDate)
errors++;
}
// you also have the option to do something fancy, like ignore null fields:
if(this.invoiceNumber != null && that.invoiceNumber != null) {
if(!this.invoiceNumber.equals(that.invoiceNumber) {
log.error(String.format("invoiceNumber are not equal: expected %s, actual %s!", this.invoiceDate, that.invoiceDate)
errors++;
}
}
// continue with all other fields ...
return errors == 0;
}
}
既然您是设置不同值的人,那么您是否需要进行额外的测试?无论如何,您可以编写自己的方法,如果断言失败,您可以在其中设置自定义测试message@Stultuske我不是那个设置不同值的人。我使用Selenium webdriver实现了自动化,它在本例中从web b检索发票字段rowser UI,然后从它们合成实际的Invoice实例,只有这样,才会有一个assert将测试设置夹具中的预期实例与从UI获得的实际实例进行比较。但在我的问题中,所有这些细节都不重要。当assertEquals失败时,如果失败,我没有任何信息,因为
invoiceDate代码>字段不同或其他一些字段不同。希望澄清。澄清,是的。但这也表明您的测试…有缺陷。如果您不知道首先放在那里的是什么,您将如何测试应该放在那里的内容?@Stlultuske我已经提到,我的预期实例是在测试夹具中设置的。所以不要急于下结论ons太快。为了节省您的时间:在测试开始时,我创建了一个具有特定值的发票实例,让我们调用它ExpectedVoice
。然后测试在UI中创建此发票并保存它。然后它打开发票并从UI中检索字段并构造另一个实例,让我们调用它RealizenVoice
。然后断言比较exPectedVoice
和实现Voice
。因此,我认为这并没有缺陷,应该是正确的。事实上,我为您简化了流程,事实上它更复杂。如果您正在编写测试,那么测试应该已经知道他们正在测试什么。测试应该简洁、简单,并且在他们试图测试的内容上具有声明性o测试它们的命名和写入方式。鉴于您是设置不同值的人,您是否需要进行其他测试?无论如何,您可以编写自己的方法,如果断言失败,您可以在其中设置自定义值message@Stultuske我不是那个设置不同值的人。我使用SeleniumWebDriver实现了自动检索fiel本发票中的发票编号