attest

Assertions, parameterized tests, and Hamcrest matchers

License

License

GroupId

GroupId

org.incava
ArtifactId

ArtifactId

attest
Last Version

Last Version

1.0.0
Release Date

Release Date

Type

Type

jar
Description

Description

attest
Assertions, parameterized tests, and Hamcrest matchers
Project URL

Project URL

https://github.com/jpace/attest
Source Code Management

Source Code Management

https://github.com/jpace/attest

Download attest

How to add to project

<!-- https://jarcasting.com/artifacts/org.incava/attest/ -->
<dependency>
    <groupId>org.incava</groupId>
    <artifactId>attest</artifactId>
    <version>1.0.0</version>
</dependency>
// https://jarcasting.com/artifacts/org.incava/attest/
implementation 'org.incava:attest:1.0.0'
// https://jarcasting.com/artifacts/org.incava/attest/
implementation ("org.incava:attest:1.0.0")
'org.incava:attest:jar:1.0.0'
<dependency org="org.incava" name="attest" rev="1.0.0">
  <artifact name="attest" type="jar" />
</dependency>
@Grapes(
@Grab(group='org.incava', module='attest', version='1.0.0')
)
libraryDependencies += "org.incava" % "attest" % "1.0.0"
[org.incava/attest "1.0.0"]

Dependencies

compile (3)

Group / Artifact Type Version
junit : junit jar [4.11,)
pl.pragmatists : JUnitParams jar [1.0.6,)
org.hamcrest : hamcrest-library jar [1.3,)

Project Modules

There are no modules declared in this project.

Overview

Attest is an extension of JUnit and JUnitParams, modeled somewhat on test/unit in Ruby, and adds Hamcrest matchers.

Usage

Assertions

org.incava.attest.Assertions contains alternatives to JUnit4 org.junit.Assert. Consistent with the test/unit and minitest libraries in Ruby, the primary assertion method is of the form:

   public static <T> T assertEqual(T expected, T actual, String msg);

The message is the last parameter, in comparision to it being the first parameter in JUnit4 Assert.assertEquals. That's because the message is considered of lesser importance than the expected value and the result -- my preference is to read the expected value as the first element in the assertion.

In comparision to Assert.assertEquals, which has a void return type, assertEqual returns the actual value. That supports a more concise and elegant style of instantiating objects "inside" the call to assertEqual.

   Type expected = new Type(expArgs);
   Type result = assertEqual(expected, new Type(args));
   // work with result

Among the variations of assertEqual, one supports assertions of C-style arrays (Object[]), including with better output on failure.

The message method converts key/value pairs to more descriptive output on failure of an assertion, providing more context than just the values being compared:

    import static org.incava.attest.Assertions.message;
    // ...
    
    @Test
    @Parameters
    @TestCaseName("{method} {index} {params}")
    public <T> void equalsTest(boolean expected, NullableObject<T> nobj, Object obj) {
        boolean result = nobj.equals(obj);
        assertEqual(expected, result, message("nobj", nobj, "obj", obj));
    }

Hamcrest Context Matcher

Hamcrest is great, as are Parameterized tests. But they don't blend especially well sometimes, since the Hamcrest output is limited in scope, and there is no (evident?) way to pass a message along with the assertions/matchers, as one can do in plain old JUnit:

    String userName = "one";
    String password = "bad";
    Status status = db.connect(userName, password);
    assertEquals("userName: " + userName + "; password: " + password,
                 Status.CONNECTED, status);

The closest in Hamcrest, using describedAs, would be:

    Status status = db.connect(userName, password);
    assertThat(status, describedAs("userName: " + userName + "; password: " + password,
                                   is(Status.CONNECTED));

But that loses the value of the expected value, with the output of the form:

Expected: userName: abc; password: bad
     but: was <INVALID_PASSWORD>

So ContextMatcher was written, providing more output, yet retaining the original comparison value:

    assertThat(status, withContext(is(Status.CONNECTED),
                                   "userName: " + userName + "; password: " + password));

Output:

Expected: is <CONNECTED> (userName: abc; password: bad)
     but: was <INVALID_PASSWORD>

The context (string) can be either before or after the associated matcher:

    assertThat(status, withContext("userName: " + userName + "; password: " + password,
                                   is(Status.CONNECTED)));

ContextMatcher accepts strings, as above, and also, in the interest of performance and simplicity, accepts Messages (org.incava.attest.Message). Using Messages instead of Strings means that toString is called only when necessary, i.e., when a matcher has failed.

Messages can be created as key/value pairs, with the static method org.incava.attest.Assertions.message. message contains either a string, or key/value pairs from which the string is generated.

    int x = 6, y = 7;
    int z = x * y;
    assertThat(z, withContext(message("x", x, "y", y), is(42)));

Hamcrest Exists Matcher

This is a common idiom:

    assertThat(object, withContext(msg, objectExpected ? notNullValue() : nullValue()));

So the ExistsMatcher supports a more concise alternative:

    assertThat(object, exists(objectExpected));

Versions

Version
1.0.0
0.0.8
0.0.6
0.0.5