简体   繁体   English

带有Scalatest的猫`Eq`'s`===`

[英]cats `Eq`'s `===` with Scalatest

I was reading Scala with Cats and in the first chapter of the book, they describe Eq usage. 我在阅读Scala with Cats ,在本书的第一章中,他们描述了Eq用法。

One of the exercises is about writing an instance of that typeclass for validating the equality of two cats . 其中一项练习是编写该类型类的实例以验证两只猫的相等性。 Consider this: 考虑一下:

Model 模型

final case class Cat(name: String, age: Int, color: String)

Typeclass instance 类型类实例

import cats.Eq
import cats.syntax.eq._
import cats.instances.string._
import cats.instances.int._
import co.alejandrome.typeclass.model.Cat

object CatsEqInstances {

  implicit val catsEq: Eq[Cat] = Eq.instance[Cat] {
    (cata, catb) =>
      cata.color === catb.color && cata.age === catb.age && cata.name === catb.name
  }

}

Unit tests 单元测试

import co.alejandrome.typeclass.model.Cat
import org.scalatest.{FlatSpec, Matchers}
import cats.instances.option._

class EqTest extends FlatSpec with Matchers{

  import CatsEqInstances._

  "Eq" should "compare two cats" in {
    val cat1 = Cat("Garfield",   38, "orange and black")
    val cat2 = Cat("Heathcliff", 33, "orange and black")

    catsEq.eqv(cat1, cat2) shouldBe false

    val cat3 = Cat("Garfield",   38, "orange and black")

    catsEq.eqv(cat1, cat3) shouldBe true
  }

  it should "compare two Optional cats" in {
    val cat1 = Cat("Garfield",   38, "orange and black")
    //val cat2 = Cat("Heathcliff", 33, "orange and black")

    val optionCat1 = Option(cat1)
    val optionCat2 = Option.empty[Cat]

    optionCat1 === optionCat2
  }

}

The first test works fine, but the second one doesn't because === operator is the Scalatest one, not the Eq one. 第一个测试可以正常工作,但是第二个则不能,因为===运算符是Scalatest而不是Eq

I explored if the typeclass has any syntax or implicit for this but I cannot find anything about it. 我探讨了类型类是否对此具有任何语法或隐式,但是我找不到任何有关它的内容。 I saw in this PR that there's a solution for this, based on Bill Venner's solution , but this is only for cats own unit tests. 我在PR中看到基于Bill Venner的解决方案可以解决问题 ,但这仅适用于猫自己的单元测试。

I was poking with EqSyntax trait but I can't figure it out how to override scalatest own implementation of === . 我当时正在使用EqSyntax特质,但我无法弄清楚如何重写 === scalatest自己的实现。

Is there any way to do this? 有什么办法吗? Or is this not implemented yet? 还是尚未实施?

Thanks 谢谢

I'm not sure if I understand your problem correctly, but it looks like you can re-use what Cats implemented for their own tests basing on the PR you referenced. 我不确定我是否正确理解了您的问题,但是您似乎可以根据您引用的PR重新使用Cat为自己的测试实施的功能。 Just change your test class definition to 只需将您的测试类定义更改为

class EqTest extends FlatSpec with Matchers with cats.tests.StrictCatsEquality  {

and then you can write tests such as 然后您可以编写测试,例如

optionCat1 === optionCat2 shouldBe false

or 要么

optionCat1 should !== (optionCat2)

and they will you use your Eq[Cat] definition (if it is imported into the scope). 他们将使用您的Eq[Cat]定义(如果将其导入到范围中)。

Essentially the idea is that ScalaTest === uses some implicit such as CanEqual . 本质上,这个想法是ScalaTest ===使用一些隐式的,例如CanEqual So if you provide (import) your custom implicit implementation - you can change how === works inside. 因此,如果您提供(导入)自定义的隐式实现,则可以更改===内部工作方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM