All Projects → unruly → java-8-matchers

unruly / java-8-matchers

Licence: MIT license
Hamcrest Matchers for Java 8 features

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to java-8-matchers

simple-excel
Generate excel sheets in Java
Stars: ✭ 85 (+269.57%)
Mutual labels:  hamcrest, hamcrest-matchers
gomatch
Library created for testing JSON against patterns.
Stars: ✭ 41 (+78.26%)
Mutual labels:  tdd, matcher
Mockk
mocking library for Kotlin
Stars: ✭ 4,214 (+18221.74%)
Mutual labels:  tdd, matcher
tddd-starter
Laravel TDDD Starter App
Stars: ✭ 23 (+0%)
Mutual labels:  tdd
ttt-tdd
Book about test-driven development with an example of making “Tic-Tac-Toe” by TDD · ❌ ⭕️ 🧪
Stars: ✭ 29 (+26.09%)
Mutual labels:  tdd
solidity-tdd
Solidity Test Driven Development Boilerplate Project
Stars: ✭ 27 (+17.39%)
Mutual labels:  tdd
baserepo
Base repository
Stars: ✭ 71 (+208.7%)
Mutual labels:  tdd
colorizzar
📗 -> 📘 Change color of png keep alpha channel in php!
Stars: ✭ 27 (+17.39%)
Mutual labels:  tdd
jest-expect-contain-deep
Assert deeply nested values in Jest
Stars: ✭ 68 (+195.65%)
Mutual labels:  matcher
utest
Lightweight unit testing framework for C/C++ projects. Suitable for embedded devices.
Stars: ✭ 18 (-21.74%)
Mutual labels:  tdd
PixelTest
Fast, modern, simple iOS snapshot testing written purely in Swift.
Stars: ✭ 56 (+143.48%)
Mutual labels:  tdd
spec-kemal
Easy testing for Kemal
Stars: ✭ 51 (+121.74%)
Mutual labels:  tdd
framework
Lightweight, open source and magic-free framework for testing solidity smart contracts.
Stars: ✭ 36 (+56.52%)
Mutual labels:  tdd
pydantic-factories
Simple and powerful mock data generation using pydantic or dataclasses
Stars: ✭ 380 (+1552.17%)
Mutual labels:  tdd
cukinia
A simple on-target system test framework for Linux
Stars: ✭ 24 (+4.35%)
Mutual labels:  tdd
typeless
Typeless: the benefits of TypeScript, without the types
Stars: ✭ 17 (-26.09%)
Mutual labels:  tdd
ginkgo4j
A Java BDD Testing Framework (based on RSpec and Ginkgo)
Stars: ✭ 25 (+8.7%)
Mutual labels:  tdd
django-test-addons
Testing support for different database system like Mongo, Redis, Neo4j, Memcache, Django Rest Framework for django
Stars: ✭ 20 (-13.04%)
Mutual labels:  tdd
serverless-tdd
Serverless TDD example
Stars: ✭ 13 (-43.48%)
Mutual labels:  tdd
kata
TDD, Refactoring kata in many languages
Stars: ✭ 14 (-39.13%)
Mutual labels:  tdd

java-8-matchers

Build Status Release Version Javadocs

⚠️ This repo had been archived. Development continues at https://github.com/mrwilson/java-8-matchers ⚠️

Hamcrest Matchers for Java 8 features.

The library contains matchers for the following types introduced with Java 8:

  • java.util.Optional (and primitive variants)
  • java.util.Stream (and primitive variants)
  • java.time.Temporal (Instant, LocalDateTime, various other calendar systems)
  • java.time.TemporalAmount (Duration and Period)

In addition, there is an API to construct matchers by using lambdas to extract data from arbitrary types and apply matchers to the result. See examples of this below.

Installation

Available from the Central Repository. In Maven style:

<dependency>
  <groupId>co.unruly</groupId>
  <artifactId>java-8-matchers</artifactId>
  <version>1.6</version>
</dependency>

A test-jar is also available to gain access to a helper for testing the error messages of failing Matchers.

<type>test-jar</type>

Examples

Below are some examples of the java-8-matchers API.

Optionals

// Contents of Optional
assertThat(Optional.of("Hi!"), OptionalMatchers.contains("Hi!"));

// Contents of Optional with Matchers
assertThat(Optional.of(4), OptionalMatchers.contains(Matchers.greaterThan(3)));

// Assert empty
assertThat(Optional.empty(), OptionalMatchers.empty());

Streams

// Stream is empty
assertThat(Stream.empty(), StreamMatchers.empty());

// Stream contains elements
assertThat(Stream.of("a", "b", "c"), StreamMatchers.contains("a", "b", "c"));

// Stream has only elements matching specified Matcher
assertThat(Stream.of("bar","baz"), StreamMatchers.allMatch(containsString("a")));

// Stream contains at least one element matching specific Matcher
assertThat(Stream.of("foo", "bar", "baz", "waldo"), StreamMatchers.anyMatch(containsString("ald")));

// Stream has declared first elements (iterates over whole stream)
assertThat(Stream.of("a","b","c","d","e"), StreamMatchers.startsWith("a", "b", "c"));

// Stream has declared first elements (only pull first 10 values)
assertThat(Stream.iterate(0,i -> i + 1), StreamMatchers.startsWith(Stream.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), 10));

// Stream matches all objects within limit
assertThat(Stream.generate(() -> 10), StreamMatchers.startsWithAll(Matchers.equalTo(10), 100));

// Stream matches at least one object within limit
assertThat(Stream.iterate(0, i -> i + 1), StreamMatchers.startsWithAny(Matchers.equalTo(10), 100));

Time

// Time is before another
assertThat(Instant.parse("2014-01-01T00:00:00.00Z"), TimeMatchers.before(Instant.parse("2015-01-01T00:00:00.00Z")));

// Time is after another
assertThat(LocalDate.parse("2015-01-01"), TimeMatchers.after(LocalDate.parse("2014-01-01")));

// Time is between two limits
assertThat(Instant.parse("2015-01-01T00:00:00.00Z"), TimeMatchers.between(
  Instant.parse("2014-01-01T00:00:00.00Z"),
  Instant.parse("2016-01-01T00:00:00.00Z")
));

// Duration is longer than another
assertThat(Duration.ofMinutes(4), TimeMatchers.longerThan(Duration.ofSeconds(4)));

// Duration is shorter than another
assertThat(Duration.ofSeconds(4), TimeMatchers.shorterThan(Duration.ofMinutes(4)));

// Period matches element-wise
assertThat(Period.of(1, 2, 3), TimeMatchers.matches(equalTo(1), equalTo(2), equalTo(3)));

Method references and lambdas

Java8Matchers enables asserting the state of objects of arbitrary types by using method references or lambdas to resolve values which can be matched by other matchers.

Say we have the following domain:

class EmailAddress {
  static EmailAddress verified(String address) {
    return new EmailAddress(address, true);
  }

  static EmailAddress unverified(String address) {
    return new EmailAddress(address, false);
  }

  String address;
  boolean verified;

  private EmailAddress(String address, boolean verified) {
    this.address = address;
    this.verified = verified;
  }

  String getAddress() {
    return address;
  }

  boolean isVerified() {
    return verified;
  }

  // equals and hashCode
}

class ContactInfo {
  String name;
  EmailAddress email;
  Instant expiration;

  String getName() {
    return name;
  }

  Instant getExpiration() {
    return expiration;
  }

  EmailAddress getEmailAddress() {
    return email;
  }
}

Following is some examples on how we can assert the state of the domain objects above:

import static co.unruly.matchers.Java8Matchers.where;
import static org.hamcrest.Matchers.is; //regular matcher from the Hamcrest library
...
ContactInfo contactInfo = // resolve ContactInfo from somewhere

// check the name is as expected
assertThat(contactInfo, where(ContactInfo::getName, is("John Doe")));

What is the point of performing the assert in this manner instead of just invoking contactInfo.getName() directly? It enables the construction of more context information in test failure messages. The Hamcrest Matcher created by the Java8Matchers.where(..)-method is able to reflect on the method reference, and, in the event of a failing test, is able to tell both that the object of type ContactInfo was not as expected, and it was specifically the method getName which yielded the unexpected value.

This is especially helpful when asserting boolean values:

import static co.unruly.matchers.Java8Matchers.where;
import static co.unruly.matchers.Java8Matchers.whereNot;
...
assertThat(EmailAddress.verified("[email protected]"), where(EmailAddress::isVerified));

assertThat(EmailAddress.unverified("[email protected]"), whereNot(EmailAddress::isVerified));

Using the where(<predicate>) or whereNot(<predicate>), instead of the non-informative "expected true, but was false" test failure messages, you will be told that there was an EmailAddress which was expected to be verified, but was not.

As shown above, matchers created using the where(..) or whereNot(..) will be able to read the method names of method references, i.e. on the form a::method. However, if resolving values using lambdas, i.e. a -> a.method(), it is not possible to resolve the actual method which has been invoked, and the failure messages will instead contain the return type from the lambda. If the return type itself is a custom domain type, it will still often be sufficiently specific:

ContactInfo contactInfo = // resolve ContactInfo from somewhere
assertThat(contactInfo, where(c -> c.getEmailAddress(), is(EmailAddress.verified("[email protected]"))));

Here, even though using a lambda instead of a method reference, the test failure message will contain that the EmailAddress of a ContactInfo-object was not as expected.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].