There is a special support for matching case classes:
Both approaches are not incompatible, you can restrict the number of fields to match the remaining fields with more precise criteria.
You need to add the specs2-shapeless
module to your project dependencies and add the org.specs2.shapeless.Projection._
import to your file.
Then you can “project” a type A
on a “smaller” type B
:
import org.specs2.shapeless.Projection._
case class User(id: Int, name: String, age: Int)
case class ExpectedUser(name: String, age: Int)
val u = User(123, "Martin", 58)
u.projectOn[ExpectedUser] must_== ExpectedUser("Martin", 58)
You to add the specs2-matcher-extra
module to your project dependencies and add the org.specs2.matcher.MatcherMacros
trait to your specification.
Then, with the matchA
matcher you can check the values of case class attributes:
// case class for a Cat
case class Cat(name: String = "", age: Int = 0, kitten: Seq[Cat] = Seq())
// a given cat
val cat = Cat(name = "Kitty", age = 6, kitten = Seq(Cat("Oreo", 1), Cat("Ella", 2)))
// this cat must be a Cat
cat must matchA[Cat]
// check the value of "name"
cat must matchA[Cat].name("Kitty")
// check the value of "age" using a matcher
def is[A](a: A) = be_==(a)
cat must matchA[Cat].age(is(6))
// check the value of "kitten" using a function returning a Result
cat must matchA[Cat].kitten((_:Seq[Cat]) must haveSize(2))
// matchers can be chained
cat must matchA[Cat]
.name("Kitty")
.age(is(6))
.kitten((_:Seq[Cat]) must haveSize(2))