scala测试失败虽然实际看起来符合预期

时间:2014-10-12 22:30:38

标签: scala unit-testing

我正在参加Scala中的Coursera课程功能编程。如果您对提供问题解决方案有疑虑,这与分配无直接关系。

我发现自己经常不清楚发生了什么。所以,我使用测试来获得洞察力。在本周的分配中包括一组测试。在测试套件中定义了几个函数 - size和asSet,后者将TweetSet转换为Set [Tweet]。我为两者创建了测试。尺寸测试工作得很好。 asSet适用于空集,但它失败并带有一个元素集。输出信息肯定会让我觉得我所做的是正确的,所以我现在不知道出了什么问题。

结果信息是:

org.scalatest.exceptions.TestFailedException: Set(User: a
Text: a body [20]) did not equal Set(User: a
Text: a body [20])

如您所见,它表明结果等于期望值。这是失败的测试:

  test("asSet: on singleton set") {
    new TestSets {
        assert(asSet(set2) === Set[Tweet](new Tweet("a", "a body", 20)))
    }
  } 

该功能定义如下(这在课程资料中提供):

  def asSet(tweets: TweetSet): Set[Tweet] = {
    var res = Set[Tweet]()
    tweets.foreach(res += _)
    res
  }

set2的定义如下(再次提供):

val set1 = new Empty
val set2 = set1.incl(new Tweet("a", "a body", 20))

推文定义如下:

class Tweet(val user: String, val text: String, val retweets: Int) {
  override def toString: String =
    "User: " + user + "\n" +
    "Text: " + text + " [" + retweets + "]"
}

我错过了什么,这个测试失败了,虽然看起来应该通过?

2 个答案:

答案 0 :(得分:0)

由于 hashCode 的实施方式,您的测试失败。

  • 要与 == 进行比较,Scala会使用在每个班级上实施的等于方法。
  • 确定实例是否包含在Set中或将其用作键Scala使用 hashCode 方法

错误的基本来源 正如您实现了 Tweet ,每个实例都是不同的,即使它包含相同的信息。

scala> val x= Set(new Tweet( "me", "test message", 1),new Tweet( "me", "test message", 1) )
  x: scala.collection.immutable.Set[Tweet] =
  Set(User: me
      Text: test message [1 ],
      User: me
      Text: test message [1 ])

 scala> x.size
 res3: Int = 2

如何实现此方法因类和案例类而异。

示例

正常班级

class Tweet(val user: String, val text: String, val retweets: Int) {
  override def toString: String = 
    s"""User: $user
    |Text: $text [$retweets ]""".stripMargin
}



scala> val x = new Tweet( "me", "test message", 1)
x: Tweet =
  User: me
  Text: test message [1 ]

scala> x == x
res0: Boolean = true

scala> x == new Tweet( "me", "test message", 1)
res1: Boolean = false

与案例类

case class Tweet(val user: String, val text: String, val retweets: Int) {
   override def toString: String = 
   s"""User: $user
       |Text: $text [$retweets ]""".stripMargin
}

scala> val x = new Tweet( "me", "test message", 1)
x: Tweet =
  User: me 
  Text: test message [1 ]

scala> x == x
res2: Boolean = true

scala> x == new Tweet( "me", "test message", 1)
res3: Boolean = true

scala> (new Tweet( "me", "test message", 1)).hashCode
res6: Int = -1967705983

scala> (new Tweet( "me", "test message", 1)).hashCode
res7: Int = -1967705983

答案 1 :(得分:0)

我相信你的问题是,在作业中你手动开发Set的实现,而另一方面你使用Scala的内部Set类型来比较它;即你正在比较不同类型的两个实例。

我相信这一行的右侧会创建一个scala.collection.immutable.Set

assert(asSet(set2) === Set[Tweet](new Tweet("a", "a body", 20)))