Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala FlatSpec在使用“应仅包含”时显示奇怪的行为_Scala_Contains_Scalatest - Fatal编程技术网

Scala FlatSpec在使用“应仅包含”时显示奇怪的行为

Scala FlatSpec在使用“应仅包含”时显示奇怪的行为,scala,contains,scalatest,Scala,Contains,Scalatest,我有一个简单的测试,测试一个特定的数组是否只包含2项 testArray应仅包含项1、项2 item1是一个Java对象,其字段只能通过setter设置,不能通过构造函数设置 如果我像这样实例化对象1: val item1 = new Item1("value1") item1.setScheme("value2) val item1 = new Item1("value1") { setScheme("value2") } 测试成功,表明它确实包含对象 但是,如果我像这样实例化obj

我有一个简单的测试,测试一个特定的数组是否只包含2项

testArray应仅包含项1、项2

item1是一个Java对象,其字段只能通过setter设置,不能通过构造函数设置

如果我像这样实例化对象1:

val item1 = new Item1("value1")
item1.setScheme("value2)
val item1 = new Item1("value1") {
   setScheme("value2")
}
测试成功,表明它确实包含对象

但是,如果我像这样实例化object1:

val item1 = new Item1("value1")
item1.setScheme("value2)
val item1 = new Item1("value1") {
   setScheme("value2")
}
测试失败了。而方案值仍以相同方式设置。 在这两种情况下,printlnite1都会导致item1value='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)
返回item1.setSchemevalue2

是否在新的Item1value1中设置ChemeValue2并返回新的Item1value1

范例

item10的类型是Item1Case类,当使用{}时,在Item1内部调用,但结果不是字符串或Int,结果是case类。您可以使用{}在case类内部进行操作,但您将始终接收case类。

匿名子类上的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的相等性断言失败。

您好,谢谢您的回复,但是我仍然不太明白这到底是如何导致测试失败的。这两种方法都会生成指向具有完全相同属性的对象的val。我也试过你的例子,但编译器并不是简单地说你不能把一个单位分配给一个空类型。这是合乎逻辑的,因为setter返回一个空单位。我将用一个新的例子解释Item1是否覆盖了equals?你能发布Item1的代码吗?@MarioGalic发布了遗留java对象的代码。我不知道第二种类型的实例化返回了一个Anon类。谢谢