Core assertion building blocks for Kotest testing framework providing foundational utilities like shouldBe for all platforms
—
The core matcher system provides the foundation for all Kotest assertions through a natural language DSL. The primary functions shouldBe, should, and shouldNot enable fluent, readable test assertions with comprehensive error reporting.
The fundamental assertion functions that form the basis of all Kotest testing.
/**
* Basic equality assertion - most commonly used assertion in Kotest
* @param expected The expected value to compare against
* @return The original value for chaining
*/
infix fun <T, U : T> T.shouldBe(expected: U?): T
/**
* Basic inequality assertion
* @param any The value that should not equal this value
* @return The original value for chaining
*/
infix fun <T> T.shouldNotBe(any: Any?): T
/**
* Apply a positive matcher to this value
* @param matcher The matcher to apply
* @return The original value for chaining
*/
infix fun <T> T.should(matcher: Matcher<T>): T
/**
* Apply a negative matcher to this value
* @param matcher The matcher to apply (result will be negated)
* @return The original value for chaining
*/
infix fun <T> T.shouldNot(matcher: Matcher<T>): T
/**
* Semantic alias for should() - use when it reads better
* @param matcher The matcher to apply
* @return The original value for chaining
*/
infix fun <T> T.shouldHave(matcher: Matcher<T>): T
/**
* Semantic alias for shouldNot() - use when it reads better
* @param matcher The matcher to apply (result will be negated)
* @return The original value for chaining
*/
infix fun <T> T.shouldNotHave(matcher: Matcher<T>): T
/**
* Apply an assertion function directly to this value (lambda-based matcher)
* @param matcher Assertion function to apply
* @return The original value for chaining
*/
infix fun <T> T.should(matcher: (T) -> Unit): TUsage Examples:
import io.kotest.matchers.*
// Basic equality
"hello" shouldBe "hello"
42 shouldBe 42
listOf(1, 2, 3) shouldBe listOf(1, 2, 3)
// Basic inequality
"hello" shouldNotBe "world"
42 shouldNotBe 43
// Using custom matchers (examples with hypothetical matchers)
"hello" should startWith("he")
"hello" shouldNot endWith("lo")
"hello" shouldHave length(5)
"hello" shouldNotHave length(6)
// Chaining assertions
val result = "hello world"
result shouldBe "hello world" shouldHave length(11)The core interface for creating custom matchers.
/**
* Interface for creating custom matchers
* @param T The type of value this matcher can test
*/
interface Matcher<T> {
/**
* Test the given value against this matcher's criteria
* @param value The value to test
* @return MatcherResult indicating pass/fail and error messages
*/
fun test(value: T): MatcherResult
}
/**
* Result of a matcher evaluation
*/
interface MatcherResult {
/** Whether the matcher passed */
val passed: Boolean
/** Error message to show when the matcher fails */
val failureMessage: String
/** Error message to show when the negated matcher fails */
val negatedFailureMessage: String
}Utility functions for creating common matchers.
/**
* Create an equality matcher
* @param expected The expected value
* @return Matcher that tests for equality
*/
fun <T> be(expected: T): Matcher<T>
/**
* Create an equality matcher with type information
* @param expected The expected value
* @return Matcher that tests for equality
*/
fun <T> equalityMatcher(expected: T): Matcher<T>
/**
* Execute a matcher against a value and return the value
* @param t The value to test
* @param matcher The matcher to apply
* @return The original value for chaining
*/
fun <T> invokeMatcher(t: T, matcher: Matcher<T>): TUsage Examples:
import io.kotest.matchers.*
// Using factory functions
"hello" should be("hello")
"hello" should equalityMatcher("hello")
// Custom matcher example
val customMatcher = object : Matcher<String> {
override fun test(value: String): MatcherResult {
val passed = value.length == 5
return object : MatcherResult {
override val passed = passed
override val failureMessage = "Expected string length 5, but was ${value.length}"
override val negatedFailureMessage = "Expected string length not to be 5"
}
}
}
"hello" should customMatcher
"hello" shouldNot customMatcherAll assertion functions return the original value, enabling fluent chaining:
val user = User("Alice", 25, "alice@example.com")
user.name shouldBe "Alice"
user.age shouldBe 25
user.email shouldBe "alice@example.com"
// Or chain multiple assertions on the same value
user.name shouldBe "Alice" shouldHave length(5)The matcher system handles null values appropriately:
val nullable: String? = null
nullable shouldBe null
val nonNull: String? = "hello"
nonNull shouldNotBe null
nonNull shouldBe "hello"The generic type system preserves type information:
val numbers: List<Int> = listOf(1, 2, 3)
val result: List<Int> = numbers shouldBe listOf(1, 2, 3)
// result is still typed as List<Int>Install with Tessl CLI
npx tessl i tessl/maven-io-kotest--kotest-assertions-shared-jvm