Custom Matchers
Learn how to define your own matchers to extend ScalaTest DSL.
We'll cover the following...
In this lesson, we’ll take a look at custom matchers. We’ll start off by refining the way we use property and boolean matchers and then define our own.
Property matchers
We can define custom property matchers by creating instances of the HavePropertyMatcher
trait. ScalaTest documentation advises doing this in a trait we can later mix into our test classes. The following snippet of code defines custom matchers for Course#title
, Course#author
, and PaidCourse#price
.
import mdipirro.educative.io.effectiveunitandintegrationtestinginscala.model.{Author, Course, PaidCourse}import org.scalatest.matchers.{HavePropertyMatchResult, HavePropertyMatcher}trait CoursePropertyMatchers:def title(expectedValue: String): HavePropertyMatcher[Course, String] =new HavePropertyMatcher[Course, String]:def apply(course: Course) =HavePropertyMatchResult(matches = course.title == expectedValue,propertyName = "title",expectedValue = expectedValue,actualValue = course.title)def author(expectedValue: Author): HavePropertyMatcher[Course, Author] =(course: Course) => HavePropertyMatchResult(matches = course.author == expectedValue,propertyName = "author",expectedValue = expectedValue,actualValue = course.author)trait PaidCoursePropertyMatchers extends CoursePropertyMatchers:def price(expectedValue: BigDecimal): HavePropertyMatcher[PaidCourse, BigDecimal] =(course: PaidCourse) => HavePropertyMatchResult(matches = course.price == expectedValue,propertyName = "price",expectedValue = expectedValue,actualValue = course.price)
A custom property matcher is simply a method whose name is the name of the matcher, returning an instance of HavePropertyMatcher[Course, String]
(lines 6, 16, and 25). This method simply binds the name of a property in the target class (Course
in this case) to the apply
method of HavePropertyMatcher
.
The second type parameter (for example, String
in HavePropertyMatcher[Course, String]
) represents the type of the expected value. In the example above, the title
matcher (line 5) is shown with verbose syntax. This syntax can be sugared to use a single abstract method, as shown in ...