Reference
Assertions API
Every public method of the assertion package, in bonsai-junit. The narrative version with worked examples is the Assertions guide.
MongoAssertions
The single static-import entry point.
package io.typecheck.bonsai.assertions;
public final class MongoAssertions {
public static MongoCollectionAssert assertThatCollection(String name);
public static MongoDocumentAssert assertThatDocument(Document document);
public static MongoChoreographyAssert assertThatChoreography();
}MongoCollectionAssert
Assertions on a collection, read lazily so they always see current state. The subject is the collection name: "orders" or "billing.invoices".
public final class MongoCollectionAssert
extends AbstractAssert<MongoCollectionAssert, String> {
public MongoCollectionAssert logOnFailure();
public MongoCollectionAssert silentOnFailure();
public MongoCollectionAssert exists();
public MongoCollectionAssert isEmpty();
public MongoCollectionAssert hasDocumentCount(long expected);
public MongoCollectionAssert hasDocumentCount(long expected,
Consumer<MongoDocumentAssert> requirements);
public MongoCollectionAssert hasDocumentCount(Matcher<? super Long> matcher);
public MongoCollectionAssert hasDocumentCount(Matcher<? super Long> matcher,
Consumer<MongoDocumentAssert> requirements);
public MongoCollectionAssert hasDocumentCountAtLeast(long expected);
public MongoCollectionAssert hasDocumentCountAtLeast(long expected,
Consumer<MongoDocumentAssert> requirements);
public MongoCollectionAssert hasSingleDocument();
public MongoCollectionAssert hasIndexOn(String field);
public MongoCollectionAssert hasUniqueIndexOn(String field);
public MongoCollectionAssert containsDocumentMatching(String filterJson);
public MongoCollectionAssert containsDocumentSatisfying(
Consumer<MongoDocumentAssert> requirements);
public MongoCollectionAssert containsExactlyOneDocumentSatisfying(
Consumer<MongoDocumentAssert> requirements);
public MongoCollectionAssert allDocumentsSatisfy(
Consumer<MongoDocumentAssert> requirements);
public MongoCollectionAssert noDocumentSatisfies(
Consumer<MongoDocumentAssert> requirements);
public MongoCollectionAssert containsDocumentSatisfying(
Matcher<? super Document> matcher);
public MongoCollectionAssert containsExactlyOneDocumentSatisfying(
Matcher<? super Document> matcher);
public MongoCollectionAssert allDocumentsSatisfy(Matcher<? super Document> matcher);
public MongoCollectionAssert noDocumentSatisfies(Matcher<? super Document> matcher);
public MongoCollectionAssert hasFieldValues(String field,
Matcher<? super List<Object>> matcher);
public ListAssert<Object> extractingField(String field);
public MongoDocumentsAssert documents();
}The predicate count overloads count only documents whose nested assertion chain passes, so they chain naturally after a total count to express a breakdown.
assertThatCollection("orders")
.hasDocumentCount(100)
.hasDocumentCount(50, d -> d.hasField("owner", "GORDON").hasField("status", "AVAILABLE"))
.hasDocumentCountAtLeast(1, d -> d.hasField("owner", "ENACT"));logOnFailure() is the default and dumps the collection when an assertion fails; silentOnFailure() opts out. extractingField(...) hands you AssertJ's ListAssert, which ends the fluent chain. Put it last. documents() takes an ordered snapshot and switches to MongoDocumentsAssert. hasFieldValues(field, matcher) is the chainable form of extractingField; both give an absent field the value null.
The Matcher overloads (3.4.0+) sit beside the long and Consumer forms without displacing them: a lambda still binds to Consumer, and containsDocumentMatching(String) is still the server-side query. The count matcher is over Long, so greaterThan(3) does not compile. Write greaterThan(3L).
MongoDocumentAssert
Assertions on a single BSON document.
public final class MongoDocumentAssert
extends AbstractAssert<MongoDocumentAssert, Document> {
public MongoDocumentAssert hasId(Object expectedId);
public MongoDocumentAssert hasIdMatching(Matcher<?> matcher);
public MongoDocumentAssert hasField(String field);
public MongoDocumentAssert hasField(String field, Object expectedValue);
public MongoDocumentAssert hasField(String field, Object expectedValue, ZoneId zone);
public MongoDocumentAssert hasFieldMatching(String field, Matcher<?> matcher);
public MongoDocumentAssert doesNotHaveField(String field);
public MongoDocumentAssert hasJsonPath(String path);
public MongoDocumentAssert hasJsonPath(String path, Object expectedValue);
public MongoDocumentAssert hasJsonPathMatching(String path, Matcher<?> matcher);
public MongoDocumentAssert matchesJson(String expectedJson, String... ignoringJsonPaths);
public MongoDocumentAssert matchesDocument(Matcher<? super Document> matcher);
public String json();
}- Field names may be dotted paths; the literal key is tried first, then the nested walk.
- Numbers compare by value across BSON types.
- JsonPath expressions run over the document's relaxed Extended JSON.
json()returns the document as relaxed Extended JSON, which is useful for building your own message or dropping into a debugger.
MongoDocumentsAssert
Ordered-snapshot assertions.
public final class MongoDocumentsAssert
extends AbstractAssert<MongoDocumentsAssert, List<Document>> {
public MongoDocumentsAssert sortedBy(String field);
public MongoDocumentsAssert ignoringFields(String... fieldsOrJsonPaths);
public MongoDocumentsAssert containsExactlyJson(String... expectedJson);
public List<Document> documents();
}ignoringFields accepts either a field name ("_id", "customer.tier") or a JsonPath ("$.lines[0].sku"); anything not starting with $ is prefixed internally.
MongoChoreographyAssert
The multi-collection flow assertion, for saga, outbox, and event-choreography tests. It does not extend AssertJ.
public final class MongoChoreographyAssert {
public MongoChoreographyAssert forId(Object idOrKeyValue);
public CollectionStep collection(String qualifiedOrPlain);
public void verify();
public final class CollectionStep {
public MongoChoreographyAssert contains();
public MongoChoreographyAssert doesNotContain();
}
}forId(...) must be called before collection(...), and verify() with no steps raises IllegalStateException. Both are mistakes that would otherwise produce a test that asserts nothing. The id matches _id first, then any top-level field with an equal value.
MongoFieldMatchers
Hamcrest matchers for field values, for use with MongoDocumentAssert.hasFieldMatching. All return Matcher<Object>.
public final class MongoFieldMatchers {
public static Matcher<Object> validObjectIdHex();
public static Matcher<Object> validUuid();
public static Matcher<Object> validIsoInstant();
public static Matcher<Object> nonBlankString();
public static Matcher<Object> matchesRegex(String regex);
public static Matcher<Object> validJson();
public static Matcher<Object> jsonPath(String path, Matcher<?> matcher);
// MongoDB-specific
public static Matcher<Object> bsonDate();
// 3.5.2: dates and Java-time thresholds, with optional persistence timezone
public static Matcher<Object> dateAfter(Object expected);
public static Matcher<Object> dateAfter(Object expected, ZoneId zone);
public static Matcher<Object> dateBefore(Object expected);
public static Matcher<Object> dateBefore(Object expected, ZoneId zone);
public static Matcher<Object> dateAtOrAfter(Object expected);
public static Matcher<Object> dateAtOrAfter(Object expected, ZoneId zone);
public static Matcher<Object> dateAtOrBefore(Object expected);
public static Matcher<Object> dateAtOrBefore(Object expected, ZoneId zone);
public static Matcher<Object> dateEqualTo(Object expected);
public static Matcher<Object> dateEqualTo(Object expected, ZoneId zone);
public static Matcher<Object> decimal128(Matcher<? super BigDecimal> matcher);
// The library's own comparison, as matchers
public static Matcher<Object> valueEqualTo(Object expected);
public static Matcher<Object> numberComparing(Matcher<? super BigDecimal> matcher);
}valueEqualTo and numberComparing (3.4.0+) exist because Hamcrest equality is equals() while the library's is by value across BSON types. hasFieldMatching(f, valueEqualTo(v)) gives the same verdict as hasField(f, v); numberComparing normalises any stored number to BigDecimal before the inner matcher sees it, and treats a non-number, NaN or ±Infinity as a mismatch rather than an error.
MongoDocumentMatchers
The MongoDocumentAssert vocabulary as standalone Matcher<Document> factories (3.4.0+), for matchesDocument, the …Satisfying collection methods, and any Hamcrest-native assertion on a Document you already hold.
public final class MongoDocumentMatchers {
public static Matcher<Document> hasField(String field);
public static Matcher<Document> hasField(String field, Object expectedValue);
public static Matcher<Document> hasFieldMatching(String field, Matcher<?> valueMatcher);
public static Matcher<Document> doesNotHaveField(String field);
public static Matcher<Document> hasJsonPath(String path);
public static Matcher<Document> hasJsonPath(String path, Object expectedValue);
public static Matcher<Document> hasJsonPathMatching(String path, Matcher<?> valueMatcher);
public static Matcher<Document> hasId(Object expectedId);
public static Matcher<Document> hasIdMatching(Matcher<?> idMatcher);
public static Matcher<Document> matchesJson(String expectedJson,
String... ignoringJsonPaths);
}Each factory delegates to the same field resolver and comparison as its MongoDocumentAssert namesake, so the verdicts match method for method. An absent field is a mismatch whatever the value matcher says. Spell “absent or matching” as anyOf(not(hasField(f)), hasFieldMatching(f, m)). A null or non-Document actual never matches, which makes a bare not(...) pass on null. A null matcher raises IllegalArgumentException.