Asserting equality
Weaver offers two approaches for asserting equality: expect.eql
and expect.same
.
expect.eql
is the better approach, but you may need to write some extra code to use it.
expect.eql
(recommended)
expect.eql(expected, found)
expect.eql
asserts for strict equality.
If you accidentally compare the wrong types of data, your code will not compile:
expect.eql(1, "one")
// error: Could not find an implicit Comparison[Any]. Does Any have an associated cats.Eq[Any] instance?
The data types you compare must have an Eq typeclass instance. You can declare one, or derive one using kittens.
case class Pet(name: String)
// A cats.Eq instance is needed
import cats.Eq
implicit val petEq: Eq[Pet] = Eq.by(_.name)
expect.eql(Pet("Maru"), Pet("Fido"))
expect.same
expect.same(expected, found)
expect.same
asserts using universal equality.
If you accidentally compare the wrong types of data, your code will compile. Your test will fail later, when it is run:
// This compiles
expect.same(1, "one")
expect.same
doesn't require an Eq
instance.
case class Dog(name: String) // No Eq instance defined
expect.same(Dog("Maru"), Dog("Fido"))
Do not use expect
You can assert for equality using expect
.
expect(1 == 2)
This is discouraged because its failure messages are poorer than expect.eql
or expect.same
. It does not display a diff of the values on the left and right side of the equality.
Use expect
along with clue
when you have other assertions. For example to assert for >
expect(clue(x) > 2)
Should I use expect.same
or expect.eql
?
- Use
expect.eql
for Scala standard datatypes such asInt
andString
. These haveEq
instances, so don't need any extra code. - Use
expect.eql
for your own data types if you prefer compile time errors at the expense of extra code. - Use
expect.same
for your own data types if you prefer runtime test failures instead of extra code.
These are described in the suite below.
Example suite
import weaver._
object ExpectationsSuite extends SimpleIOSuite {
pureTest("expect.eql for standard data types") {
expect.eql(1, 2)
}
import cats.Eq
case class Pet(name: String)
implicit val eqPet: Eq[Pet] = Eq.by[Pet, String](_.name)
pureTest("expect.eql for user-defined data types") {
expect.same(Pet("Maru"), Pet("Fido"))
}
// Note that we don't have an instance of Eq[Dog]
// anywhere in scope
case class Dog(name: String)
pureTest("expect.same relaxed equality comparison") {
expect.same(Dog("Maru"), Dog("Fido"))
}
}
Example suite report
repl.MdocSessionMdocAppExpectationsSuite - expect.eql for standard data types 34ms - expect.eql for user-defined data types 33ms - expect.same relaxed equality comparison 32ms *************FAILURES************* repl.MdocSessionMdocAppExpectationsSuite - expect.eql for standard data types 34ms
Values not equal: (asserting_equality.md:118)
=> Diff (- obtained, + expected)
-2
+1 - expect.eql for user-defined data types 33ms
Values not equal: (asserting_equality.md:126)
=> Diff (- obtained, + expected)
-Pet(Fido)
+Pet(Maru) - expect.same relaxed equality comparison 32ms
Values not equal: (asserting_equality.md:134)
=> Diff (- obtained, + expected)
-Dog(Fido)
+Dog(Maru) Total 3, Failed 3, Passed 0, Ignored 0, Cancelled 0