Strikt logo

Strikt is an assertion library for Kotlin intended for use with a test runner such as JUnit or Spek.

Strikt gives you…

A powerful fluent API

Type-safe fluent assertions

val subject = "The Enlightened take things Lightly"
expectThat(subject)
  .hasLength(35)
  .matches(Regex("[\\w\\s]+"))
  .startsWith("T")

Collection handling

Flexible assertions about collections

val subject = listOf("Eris", "Thor", "Anubis", "Ra")
expectThat(subject)
  .contains("Eris", "Thor", "Anubis")

“Narrow” the assertion to elements or ranges

expectThat(subject)[0].isEqualTo("Eris")

Make grouping assertions

val subject = Deity.values().map { it.toString() }
expectThat(subject)
  .isNotEmpty()
  .any { startsWith("E") }

“Soft” assertions

Use lambdas to execute multiple assertions on a subject at once…

val subject = "The Enlightened take things Lightly"
expectThat(subject) {
  hasLength(5)           // fails
  matches(Regex("\\d+")) // fails
  startsWith("T")        // still evaluated and passes
}

…with structured diagnostics of those that fail

▼ Expect that "The Enlightened take things Lightly":
  ✗ has length 5 : found 35
  ✗ matches the regular expression /\d+/ : found "The Enlightened take things Lightly"
  ✓ starts with "T"

Use lambdas to execute assertions on multiple subjects at once…

val person1 = Person(name = "David")
val person2 = Person(name = "Ziggy")
expect {
  that(person1.name).isEqualTo("David")
  that(person2.name).isEqualTo("Ziggy")
}

Strong typing

Assertion functions can "narrow" the type of the assertion

val subject: Any? = "The Enlightened take things Lightly"
expectThat(subject)            // type: Assertion<Any?>
  .isNotNull()                 // type: Assertion<Any>
  .isA<String>()               // type: Assertion<String>
  .matches(Regex("[\\w\\s]+"))
// only available on Assertion<CharSequence>

Assertions can "map" to properties and method results in a type safe way:

val subject = Pantheon.NORSE
expectThat(subject)
  .get(Pantheon::ruler) // reference to a property
  .get { toString() } // return type of a method call
  .isEqualTo("Odin")

Extensibility

Custom assertions are extension functions

fun Assertion.Builder<LocalDate>.isStTibsDay() =
  assert("is St. Tib's Day") {
    when (MonthDay.from(it)) {
      MonthDay.of(2, 29) -> pass()
      else -> fail()
    }
  }
expectThat(LocalDate.of(2020, 2, 29)).isStTibsDay()

Custom mappings are extension properties

val Assertion.Builder<Pantheon>.realm: Assertion.Builder<String>
  get() = get { "$ruler to $underworldRuler" }

  val subject = Pantheon.NORSE
  expectThat(subject)
    .realm
    .isEqualTo("Odin to Hel")