我有一个简单的测试,我测试一个特定的数组是否仅包含2个项目。
testArray should contain only (item1, item2)
item1是一个Java对象,其字段只能通过setter设置,而不能通过构造函数设置。
如果我这样实例化对象1:
val item1 = new Item1("value1")
item1.setScheme("value2)
测试成功表明它确实包含对象。
但是,如果我像这样实例化object1:
val item1 = new Item1("value1") {
setScheme("value2")
}
测试失败。虽然方案值仍以相同方式设置。
在两种情况下,println(item1)
都会导致item1(value='value1', scheme='value2')
有人知道FlatSpec为什么以不同的方式对待这些案件吗?
Item1的代码(出于兼容性原因,将字段重命名)
public class Item1 extends LanguageTokenizedString {
private static final long serialVersionUID = -8903312231226570431L;
protected String scheme;
public Item1() {
}
public Item1(String value) {
super(value);
}
public Item1(String value, String language) throws InvalidLanguageTokenException {
super(value, language);
}
public Item1(String value, Locale locale) throws InvalidLanguageTokenException {
super(value, locale);
}
public Item1(String value, String language, String scheme) throws InvalidLanguageTokenException {
super(value, language);
this.setScheme(scheme);
}
public Item1(String value, Locale locale, String scheme) throws InvalidLanguageTokenException {
super(value, locale);
this.setScheme(scheme);
}
public String getScheme() {
return this.scheme;
}
public final void setScheme(String scheme) {
this.scheme = scheme;
}
public boolean equals(Object obj) {
boolean equals = false;
if (obj != null) {
if (obj == this) {
equals = true;
} else if (obj.getClass().equals(this.getClass())) {
Item1 other = (Item1)obj;
equals = (new EqualsBuilder()).append(this.value, other.value).append(this.scheme, other.scheme).append(this.schemeId, other.schemeId).append(this.language, other.language).isEquals();
}
}
return equals;
}
public boolean shallowEquals(Object obj) {
boolean shequals = false;
if (obj != null) {
if (obj == this) {
shequals = true;
} else if (obj.getClass().equals(this.getClass())) {
Item1 other = (Item1)obj;
shequals = (new EqualsBuilder()).append(this.value, other.value).append(this.scheme, other.scheme).append(this.schemeId, other.schemeId).isEquals();
}
}
return shequals;
}
public int hashCode() {
return (new HashCodeBuilder(23, 29)).append(this.value).append(this.scheme).append(this.schemeId).append(this.language).toHashCode();
}
public boolean isComplete() {
return true;
}
}
答案 0 :(得分:3)
getClass
与基类上的getClass
不同。例如
val itemA = new Item1("value1")
itemA.setScheme("value2")
val itemB = new Item1("value1") {
setScheme("value2")
}
println(itemA.getClass)
println(itemB.getClass)
println(itemA.getClass == itemB.getClass)
应输出
class example.Item1
class example.HelloSpec$$anon$1
false
我们看到的getClass
两者有所不同。这会使覆盖的Item1.equals
在以下检查中失败
if (obj.getClass().equals(this.getClass())) ...
这会使ScalaTests的相等性声明失败。
答案 1 :(得分:1)
这些是不同的解决方案。
val item1 = new Item1("value1")
item1.setScheme("value2)
返回item1.setScheme("value2)
和
val item1 = new Item1("value1") {
setScheme("value2")
}
在setScheme("value2")
内进行new Item1("value1")
并返回new Item1("value1")
示例
case class Item1(a: String){
def setScheme(a:Int): Int ={
a
}
}
val item10: Item1 = new Item1("value1"){
setScheme(1)
}
item10.a: String
item10.setScheme(1): Int
val item11 = new Item1("value1")
val item2: Int = item11.setScheme(1)
item2
item10
的类型为Item1
(case class
),当您使用{}
时,您在Item1
内调用,但结果不是{ {1}}或String
,结果为Int
。您可以使用case class
在{}
内部进行操作,但始终可以恢复case class
。