如何在Java Map上执行包含allOf断言?
以下内容不起作用
val testMap = new java.util.LinkedHashMap[Int, Int]()
testMap.put(1,2)
testMap.put(2,4)
testMap.put(3,6)
testMap should contain allOf (1->2, 2->4, 3->6)
它提供
{1=2, 2=4, 3=6} did not contain all of ((1,2), (2,4), (3,6))
医生说
聚合伴随对象提供为类型GenTraversable[E]、java.util.Collection[E]聚合[L],java.util.Map[K,V],字符串,数组[E]。
--http://www.scalatest.org/user_guide/using_matchers#workingWithAggregations
我做错了什么?
Scala v2.11
ScalaTest v3.1.1
Java和Scala集合支持的语法之间需要注意的一个区别是,在Java中,Map不是Collection的子类型,并且实际上没有定义元素类型。您可以通过entrySet方法向Java Map请求"entrySet",该方法将返回封装在一组Java.util.Map.entry中的Map的键/值对,但Map实际上不是entry的集合。然而,为了使Java映射更容易使用,ScalaTest匹配器允许您将Java映射视为Entry的集合,并在org.ScalaTest.Entry中定义了Java.util.Map.Entry的方便实现。--http://www.scalatest.org/user_guide/using_matchers#javaCollectionsAndMaps
尝试:
val testMap = new java.util.LinkedHashMap[Int, Int]()
testMap.put(1,2)
testMap.put(2,4)
testMap.put(3,6)
testMap should contain allOf (Entry(1, 2), Entry(2, 4), Entry(3, 6))
或者考虑CollectionConverters
import scala.jdk.CollectionConverters._
testMap.asScala should contain allOf (1->2, 2->4, 3->6)
如果我们希望维护以下DSL
testMap should contain allOf (1->2, 2->4, 3->6)
然后我们可以提供Aggregating
类型类的自定义实例,它比较Entry
与Scala元组的相等性
trait JavaMapHelpers {
def javaEntryEqualsScalaTuple[K, V]: Equality[java.util.Map.Entry[K, V]] =
(a: java.util.Map.Entry[K, V], b: Any) => b match {
case (k, v) => a.getKey == k && a.getValue == v
case _ => false
}
implicit def aggregatingNatureOfJavaMapWithScalaTuples[K, V, JMAP[k, v] <: java.util.Map[k, v]]: Aggregating[JMAP[K, V]] =
Aggregating.aggregatingNatureOfJavaMap(javaEntryEqualsScalaTuple)
def javaMap[K, V](elements: (K, V)*): java.util.LinkedHashMap[K, V] = {
val m = new java.util.LinkedHashMap[K, V]
elements.foreach(e => m.put(e._1, e._2))
m
}
}
class JavaMapSpec extends AnyFlatSpec with Matchers with JavaMapHelpers {
"Java Map" should "be checkable with Scala tuples" in {
javaMap((1,2), (2,4), (3,6)) should contain allOf (1->2, 2->4, 3->6)
}
}
定义将JavaEntry
与Scala元组进行比较的自定义等式是有效的,因为containsAllOf
在Java映射上调用entrySet
,然后使用提供的Equality
进行检查
def containsAllOf(map: JMAP[K, V], elements: scala.collection.Seq[Any]): Boolean = {
checkAllOf(map.entrySet.asScala, elements, equality)
}