设置一些集成测试,我遇到了域类相等的问题。在正常执行期间,相等性按预期工作,但在通过集成测试测试Service方法时,相等性测试将返回false。
一个服务(在测试用例的setUp()中调用)将一个Domain对象放入会话
SomeService {
setSessionVehicle(String name) {
Vehicle vehicle = Vehicle.findByName(name)
session.setAttribute("SessionVehicle", vehicle)
}
getSessionVehicle() {
return session.getAttribute("SessionVehicle")
}
}
在其他服务的其他地方,我加载一个对象并确保关联的属性对象与会话值匹配:
OtherService {
getEngine(long id) {
Vehicle current = session.getAttribute("SessionVehicle")
Engine engine = Engine.get(id)
if(!engine.vehicle.equals(current)) throw Exception("Blah blah")
}
}
这在正常操作期间按预期工作,防止加载错误的引擎(好吧,我清理了类名,假装它有意义)。但是在集成测试中,.equals()在成功时会失败:
Vehicle testVehicle
setUp() {
Vehicle v = new Vehicle("Default")
v.save()
someService.setSessionVehicle("Default")
testVehicle = someService.getSessionVehicle()
}
testGetEngine() {
List<Engine> engines = Engine.findAllByVehicle(testVehicle)
//some assertions and checks
Engine e = otherService.getEngine(engines.get(0).id)
}
findAll()
调用正确地返回会话中与车辆关联的所有引擎的列表,但是当我尝试按ID查找单个引擎时,找到会话车辆与车辆的相等性检查引擎失败。此时只创建了一辆车,并且Exception消息显示会话Vehicle和Engine.Vehicle存在并且值相同。
如果我在testCase本身尝试此等式检查,它会失败,但我可以更改testCase以检查成功的if(vehicle.id == sessionVehicle.id)
,但我并不热衷于更改我的生产代码以便满足整合测试。
在我的测试用例中设置这些域对象时,我做错了什么,我应该采取不同的做法?
答案 0 :(得分:3)
首先,您正在进行的等式检查只是检查引用。您不应该使用默认的equals方法进行检查,更好地覆盖域类中的equals方法。
有两种方法可以覆盖equals方法:
1)您可以使用IDE自动生成equals方法的代码(很多空检查等)
2)首选方式:您可以使用Apache Commons项目中的EqualsBuilder和HashCodeBuilder类。该库应该已经可供您的应用程序使用,或者下载JAR文件并放在lib中。
以下是使用EqualsBuilder的示例代码:
boolean equals(o) {
if ( !(o instanceof Vehicle) ) {
return false
}
def eb = new EqualsBuilder()
eb.append(id, o.id)
eb.append(name, o.name)
eb.append(otherProperties, o.otherProperties)
....
return eb.isEquals()
}
另一点是:你如何在服务中获得会话?来自RequestContextHolder?最好不要直接从服务访问会话,而是将值作为方法参数发送到服务中。