FlatSpec отображает странное поведение при использовании «должен содержать только» - PullRequest
2 голосов
/ 13 мая 2019

У меня есть простой тест, в котором я проверяю, содержит ли конкретный массив только 2 элемента.

testArray should contain only (item1, item2)

item1 - это объект Java, поле которого можно установить только с помощью установщика, но не через конструктор.

если я создаю экземпляр объекта 1 следующим образом:

val item1 = new Item1("value1")
item1.setScheme("value2)

Тест успешен, он говорит, что содержит объект.

Однако, если я создаю экземпляр object1 следующим образом:

val item1 = new Item1("value1") {
   setScheme("value2")
}

тест не пройден. При этом значение схемы по-прежнему задается таким же образом. A 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;
  }
}

Ответы [ 2 ]

3 голосов
/ 13 мая 2019

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 голос
/ 13 мая 2019

Это разные решения.

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, но результат неString или Int, результат - case class.Вы можете использовать {} для работы внутри case class, но вы всегда получите case class.

...