FlatSpec 在使用 'should contain only' 时显示奇怪的行为
FlatSpec displays strange behaviour while using 'should contain only'
我有一个简单的测试,我测试一个特定的数组是否只包含 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;
}
}
这些是不同的解决方案。
val item1 = new Item1("value1")
item1.setScheme("value2)
returns item1.setScheme("value2)
和
val item1 = new Item1("value1") {
setScheme("value2")
}
setScheme("value2")
在new Item1("value1")
和returnsnew 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
里面调用,结果却不是一个String
或一个Int
,结果是case class
。您可以使用 {}
在 case class
内操作,但您总是会收到 case class
.
匿名子 class 上的 getClass
不同于基础 class 上的 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
false
我们看到 getClass
两者不同。这使得被覆盖的 Item1.equals
在接下来的检查
中失败
if (obj.getClass().equals(this.getClass())) ...
这使得 ScalaTests 的等式断言失败。
我有一个简单的测试,我测试一个特定的数组是否只包含 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;
}
}
这些是不同的解决方案。
val item1 = new Item1("value1")
item1.setScheme("value2)
returns item1.setScheme("value2)
和
val item1 = new Item1("value1") {
setScheme("value2")
}
setScheme("value2")
在new Item1("value1")
和returnsnew 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
里面调用,结果却不是一个String
或一个Int
,结果是case class
。您可以使用 {}
在 case class
内操作,但您总是会收到 case class
.
getClass
不同于基础 class 上的 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
false
我们看到 getClass
两者不同。这使得被覆盖的 Item1.equals
在接下来的检查
if (obj.getClass().equals(this.getClass())) ...
这使得 ScalaTests 的等式断言失败。