我正在尝试为返回包含数组的类的元组的函数编写单元测试。
由于数组的原因,简单assert(out === expectedOut)或out should be(expectedOut)不比较 LHS 和 RHS 上的类的内容。ScalaTest 中有没有一种巧妙的方法可以做到这一点?
我看过自定义匹配器,但我不确定这是否是我想做的事情的最佳方法。因此,任何来自专家经验的信息将不胜感激。
编辑:这是一个似乎并非如此的情况:
object Utils {
case class Product(id: Int, prices: Array[Int])
def getProductInfo(id: Int, prices: Array[Int]): Option[Product] = {
val sortedPrices = prices.sortWith(_ < _)
Some(Product(id, sortedPrices))
}
}
---
import org.scalatest._
import Utils._
class DataProcessorSpec extends FlatSpec with Matchers with OptionValues {
val id = 12345
val priceList = Array(10,20,30)
val prod = Utils.getProductInfo(id, priceList)
val expectedProd = Some(Utils.Product(id, priceList))
"A DataProcessorSpec" should "return the correct product information" in {
prod should be(expectedProd)
}
}
Run Code Online (Sandbox Code Playgroud)
sortWith据我所知,测试失败是因为这会导致创建一个新数组,从而指向不同的内存位置。
更新:通过代码示例,这更清楚:
比较失败,因为shoud be使用案例类的equals函数来执行比较,并且案例类不会“深入”比较数组 - 这意味着,正如您所怀疑的那样,不同的实例将不相等(请参阅此处的更多信息)。
解决方法:
分别验证案例类的每个“部分”的相等性:
prod.get.prices should be(expectedProd.get.prices)
prod.get.id should be(expectedProd.get.id)
Run Code Online (Sandbox Code Playgroud)如果 usingArray不是必须的,你可以将 case 类更改为 use Seq[Int],这将使测试通过,因为 aSeq的实现equals 是“深”的
比较数组:
当“单独”比较时,数组将按预期(“深度”)通过 Matchers' 进行比较should be:
arr1 should be(arr2) // true if contents is the same
Run Code Online (Sandbox Code Playgroud)
如果您只是想比较内容,而不验证它out确实是一个Array,您可以使用theSameElementsInOrderAs:
arr1 should contain theSameElementsInOrderAs arr2
Run Code Online (Sandbox Code Playgroud)