2016-04-06 45 views
2

我正在尝试为返回包含数组的类的元组的函数编写单元测试。ScalaTest深度比较最佳实践

简单的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) 
    } 
} 

测试失败,因为sortWith导致创建一个新的数组,并因此指向不同的存储位置,据我所知。

+0

您能否提供一段代码?你可以像Tzach指出的那样使用匹配器,但我不完全确定你在这里试图维护什么。 – manub

回答

2

UPDATE:与代码示例,这是清晰的:因为shoud be使用案例类的equals函数来执行比较

比较失败,和案例类不比较数组“深” - 这意味着,如你所怀疑的那样,不同的情况将不相同(见更多信息here)。

解决方法

  1. 分别验证每个案例类的 “部分” 的平等:

    prod.get.prices should be(expectedProd.get.prices) 
    prod.get.id should be(expectedProd.get.id) 
    
  2. 如果使用Array是不是必须的,你可以改变的情况下类使用Seq[Int],这会使测试通过,因为equals的执行是 “深”

比较数组

当 “自己” 相比,符合市场预期( “深”)的匹配器should be阵列进行了比较:

arr1 should be(arr2) // true if contents is the same 

如果您只想比较内容,而不验证out确实是Array,则可以使用theSameElementsInOrderAs

arr1 should contain theSameElementsInOrderAs arr2 
+0

很酷,谢谢!有没有办法让它也可以在Option上使用? – Ian

+1

对于选项,你可以简单地使用'out应该是(expectedOut)',比较_is_“深”。实际上,这也适用于阵列(!) –

+0

除非我错过了一些不起作用的东西(请参阅上面编辑的代码示例)。 – Ian