针对’应该包含’的最新自定义匹配器
这是我经常遇到的情况,但我还没有找到解决方案.
假设您有一个人员列表,您只想验证人名. persons.map(_.name) should contain theSameElementsAs(List("A","B")) 相反,我宁愿写这个 val toName: Person => String = _.name persons should contain theSameElementsAs(List("A","B")) (after mapping toName) 因为这就是你怎么说的. 但有时,您希望使用自定义匹配器,该匹配器不仅仅匹配对象的一个??属性.怎么可能使用 persons should contain(..) 语法,但不知何故能够使用自定义匹配器? 我可以使用Hamcrest匹配器使用JUnit或TestNG轻松解决这两种情况,但我还没有找到使用ScalaTest执行此操作的方法. 我试图使用Explicitly trait中的’after being’语法,但这是不可能的,因为它采用’Normalization’来定义’normalized’方法对参数和返回类型使用相同的类型.所以不可能将Person更改为String. 欢迎任何建议. 解决方法
您可以通过决定和适度滥用平等特征来管理类似的事情.这是因为Equality trait的areEqual方法接受泛型类型的参数和Any类型的参数,因此您可以使用它来比较Person和String,并通过简单地获取Equality对象来确定您不需要与常态.
import org.scalactic.Equality import org.scalatest.{FreeSpec,Matchers} final class Test extends FreeSpec with Matchers { case class Person(name: String) val people = List(Person("Alice"),Person("Eve")) val namesBeingEqual = MappingEquality[Person,String](p => p.name) "test should pass" in { (people should contain theSameElementsAs List("Alice","Eve"))( decided by namesBeingEqual) } "test should fail" in { (people should contain theSameElementsAs List("Alice","Bob"))( decided by namesBeingEqual) } case class MappingEquality[S,T](map: S => T) extends Equality[S] { override def areEqual(s: S,b: Any): Boolean = b match { case t: T => map(s) == t case _ => false } } } 我不确定我是否会说这是一个好主意,因为它并不像人们期望的任何称为Equality的行为那样完美,但它有效. 您甚至可以通过隐式转换将其添加到after之后获取您建议的beingMapped语法: implicit class AfterExtensions(aft: TheAfterWord) { def beingMapped[S,T](map: S => T): Equality[S] = MappingEquality(map) } } 我确实试过通过Uniformity trait来实现它,它有类似的方法涉及Any,但遇到了问题,因为规范化是错误的方法:我可以从你的例子创建Uniformity [String]对象,但不是Uniformity [人]一个. (原因是有一个规范化的方法返回用于构造Equality对象的泛型类型,这意味着为了将字符串与字符串进行比较,左侧输入必须是一个字符串.)这意味着唯一的写入方式与正常情况下的预期vs实际值相反: "test should succeed" in { val mappedToName = MappingUniformity[Person,String](person => person.name) (List("Alice","Eve") should contain theSameElementsAs people)( after being mappedToName) } case class MappingUniformity[S,T](map: S => T) extends Uniformity[T] { override def normalizedOrSame(b: Any): Any = b match { case s: S => map(s) case t: T => t } override def normalizedCanHandle(b: Any): Boolean = b.isInstanceOf[S] || b.isInstanceOf[T] override def normalized(s: T): T = s } 绝对不是你通常想写这个的方式. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |