CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scala-js--scalajs-junit-test-runtime

JUnit test runtime for Scala.js - provides the runtime infrastructure for running JUnit tests compiled with Scala.js

Pending
Overview
Eval results
Files

hamcrest-matchers.mddocs/

Hamcrest Matchers

Hamcrest provides a library of matcher objects for building test expressions. Matchers offer readable and composable assertions with detailed failure messages that clearly describe what was expected versus what was actually encountered.

Core Matcher Interface

trait Matcher[T] {
  def matches(actual: AnyRef): Boolean
  def describeTo(description: Description): Unit
}

trait Description {
  def appendText(text: String): Description
  def appendDescriptionOf(value: SelfDescribing): Description
  def appendValue(value: AnyRef): Description
}

Matcher Factories

CoreMatchers Object

object CoreMatchers {
  def is[T](matcher: Matcher[T]): Matcher[T]
  def is[T](value: T): Matcher[T]
  def isA[T](typ: Class[T]): Matcher[T]
  def any[T](typ: Class[T]): Matcher[T]
  def instanceOf[T](typ: Class[_]): Matcher[T]  
  def not[T](matcher: Matcher[T]): Matcher[T]
  def not[T](value: T): Matcher[T]
  def notNullValue(): Matcher[AnyRef]
  def notNullValue[T](typ: Class[T]): Matcher[T]
  def nullValue(): Matcher[AnyRef]
  def nullValue[T](typ: Class[T]): Matcher[T]
  def equalTo[T](operand: T): Matcher[T]
  def equalToObject(operand: AnyRef): Matcher[AnyRef]
}

Basic Matchers

Identity and Decoration

def is[T](matcher: Matcher[T]): Matcher[T]
def is[T](value: T): Matcher[T]

Usage:

import org.hamcrest.CoreMatchers._
import org.junit.Assert.assertThat

assertThat(userName, is("admin"))
assertThat(userAge, is(greaterThan(18)))
assertThat(result, is(notNullValue()))

The is matcher is purely decorative - it wraps another matcher to improve readability without changing behavior.

Type Checking

def any[T](typ: Class[T]): Matcher[T]
def instanceOf[T](typ: Class[_]): Matcher[T]  
def isA[T](typ: Class[T]): Matcher[T]

Usage:

assertThat(result, instanceOf(classOf[String]))
assertThat(exception, isA(classOf[IllegalArgumentException]))
assertThat(value, any(classOf[Number]))
  • instanceOf: Matches if the actual value is an instance of the specified class
  • isA: Alias for instanceOf with decorative "is a" reading
  • any: Matches any instance of the specified type

Null Value Matchers

def nullValue(): Matcher[AnyRef]
def nullValue[T](typ: Class[T]): Matcher[T]
def notNullValue(): Matcher[AnyRef]
def notNullValue[T](typ: Class[T]): Matcher[T]

Usage:

assertThat(optionalValue, nullValue())
assertThat(optionalValue, nullValue(classOf[String]))
assertThat(requiredField, notNullValue())
assertThat(user.getName(), notNullValue(classOf[String]))

Negation Matcher

def not[T](matcher: Matcher[T]): Matcher[T]
def not[T](value: T): Matcher[T]

Usage:

assertThat(result, not(nullValue()))
assertThat(status, not("inactive"))
assertThat(age, not(lessThan(0)))

The not matcher inverts any other matcher, providing clear negation with appropriate error messages.

Matcher Integration with Assert

def assertThat[T](actual: T, matcher: Matcher[T]): Unit
def assertThat[T](reason: String, actual: T, matcher: Matcher[T]): Unit

Usage:

// Basic matcher assertion
assertThat(result.size(), is(5))

// With custom message
assertThat("User list should not be empty", users, not(nullValue()))

// Composed matchers
assertThat(user.getStatus(), is(not("inactive")))
assertThat(response.getCode(), is(instanceOf(classOf[Integer])))

Advanced Matcher Classes

Base Matcher Implementation

abstract class BaseMatcher[T] extends Matcher[T] {
  def describeTo(description: Description): Unit
  def matches(actual: AnyRef): Boolean
}

Diagnosing Matcher

abstract class DiagnosingMatcher[T] extends BaseMatcher[T] {
  def matches(item: AnyRef, mismatchDescription: Description): Boolean
  final def matches(item: AnyRef): Boolean
}

DiagnosingMatcher provides enhanced mismatch descriptions by allowing matchers to describe why a match failed.

Matcher Assertions vs Regular Assertions

Regular Assert:

assertEquals("Expected active user", "active", user.getStatus())
// Error: Expected active user expected:<active> but was:<inactive>

Hamcrest Matcher:

assertThat(user.getStatus(), is("active"))
// Error: Expected: is "active" but: was "inactive"

Hamcrest matchers provide:

  • More readable error messages
  • Composable expressions
  • Better type safety
  • Consistent failure reporting format

Custom Matcher Implementation

import org.hamcrest.{Description, BaseMatcher}

class GreaterThanMatcher(threshold: Int) extends BaseMatcher[Int] {
  def matches(actual: AnyRef): Boolean = {
    actual.asInstanceOf[Int] > threshold
  }

  def describeTo(description: Description): Unit = {
    description.appendText(s"greater than $threshold")
  }
}

def greaterThan(threshold: Int): Matcher[Int] = new GreaterThanMatcher(threshold)

// Usage
assertThat(score, greaterThan(80))

Error Reporting and Description

Hamcrest matchers automatically generate descriptive error messages:

  • Expected: What the matcher was looking for
  • Actual: What was actually provided
  • Mismatch: Why the match failed (for DiagnosingMatcher)

This provides clear, consistent test failure reporting across all matcher types.

Install with Tessl CLI

npx tessl i tessl/maven-org-scala-js--scalajs-junit-test-runtime

docs

array-assertions.md

core-assertions.md

exception-handling.md

hamcrest-matchers.md

index.md

test-assumptions.md

test-lifecycle.md

test-runners.md

tile.json