在编写单元测试时,我经常遇到这样的情况,即测试中某些对象的 equals() - 在 assertEquals 中 - 的工作方式应该不同于它的工作方式在实际环境中。以一些接口(interface) ReportConfig 为例。它有 id 和其他几个字段。从逻辑上讲,当它们的 id 匹配时,一个配置等于另一个配置。但是当涉及到测试一些特定的实现时,比如 XmlReportConfig,显然我想匹配所有 字段。一种解决方案是在测试中不使用 equals,只是遍历对象属性或字段并比较它们,但这似乎不是一个好的解决方案。
因此,除了这种特定类型的情况,我想从语义上而非技术上找出实现 equals 的最佳实践。
最佳答案
what are best practices to implement equals, semantically, not technically.
在 Java 中,equals 方法真的应该被认为是 "identity equals"因为它如何与 Collection 和 Map 实现集成。请考虑以下事项:
public class Foo() {
int id;
String stuff;
}
Foo foo1 = new Foo(10, "stuff");
fooSet.add(foo1);
...
Foo foo2 = new Foo(10, "other stuff");
fooSet.add(foo2);
如果 Foo 标识是 id 字段,那么第二个 fooSet.add(...) 应该不 添加另一个元素到 Set 但应该返回 false 因为 foo1 和 foo2 有相同的 id 。如果您定义 Foo.equals(和 hashCode)方法以包含 both id 和 stuff 字段,那么这可能会被破坏,因为 Set 可能包含 2 个对具有相同 id 字段的对象的引用。
如果您没有将对象存储在 Collection(或 Map)中,那么您不必定义 equals 方法方式,然而它被许多人认为是不好的形式。如果将来您确实将它存储在Collection 中,那么事情就会被破坏。
如果我需要测试所有字段是否相等,我倾向于编写另一种方法。像 equalsAllFields(Object obj) 之类的东西。
然后你会做这样的事情:
assertTrue(obj1.equalsAllFields(obj2));
此外,正确的做法是不定义考虑可变字段的equals 方法。当我们开始谈论类层次结构时,问题也变得困难起来。如果子对象将 equals 定义为其局部字段 和 基类 equals 的组合,则其对称性已被破坏:
Point p = new Point(1, 2);
// ColoredPoint extends Point
ColoredPoint c = new ColoredPoint(1, 2, Color.RED);
// this is true because both points are at the location 1, 2
assertTrue(p.equals(c));
// however, this would return false because the Point p does not have a color
assertFalse(c.equals(p));
我强烈推荐的更多阅读是这个伟大页面中的“陷阱 #3:根据可变字段定义等于”部分:
一些额外的链接:
哦,为了后代,无论您选择比较哪些字段来确定相等性,您都需要在 hashCode 计算中使用相同的字段。 equals 和 hashCode 必须是对称的。如果两个对象相等,则它们必须具有相同的散列码。反之不一定成立。
关于java - 为 equals() 实现选择字段的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9739150/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我