'should contain allOf' 在 java.util.Map 上?



如何在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)
}

相关内容

最新更新