Skip to content

Enhancement for JUnit to take advantage of Java 8

Notifications You must be signed in to change notification settings

ghostcity/j8unit

 
 

Repository files navigation

J8Unit And The J8Unit Repository

J8Unit combines the power of JUnit4 and Java 8. Briefly spoken, it comes along with:

  • some fancy assert methods that can take CharSequence or Supplier<? extends CharSequence> as its AssertionError message,
  • an extended TestClass model that (in addition to the JUnit4 model) detects test methods which are specified as default interface methods,
  • a Java-8-based reusable Tests API that (a) allows API developer to publish their API with accompanying tests and (b) allows programmer to verify its custom implementations against these behaviour expectations,
  • few additional test runners that (in addition to the JUnit4 runners) execute test methods which are specified as default interface methods,
  • a repository of reusable tests (called the J8Unit Repository) that contains an instantly growing number of reusable tests that relate to all Java types of Java 8.

You can read a brief 5-minute description right here in the below sections.

Spiced with few more information, you can read a condensed 15-minute description in J8Unit in a Nutshell. Depending on whether you are using an existing API or you are programming a new API, you should focus on the according chapter.

If you are interested in details, you should dive into the comprehensive descriptions or just read the J8Unit cover story of the Java Magazin 2.16.

Table Of Contents

  1. J8Unit And The J8Unit Repository
    1. Java-8-Based TestClass Model
    2. The Reusable Tests API
    3. The J8Unit Repository
    4. The J8Unit Test Runners
    5. Additional Assert Methods

Java-8-Based TestClass Model

One of the new features of Java 8 is the default implementation of interface methods. Obviously, such methods can be tests too; However, JUnit4 does not detect these methods. Fortunately, the JUnit4 TestClass model only needs a slightly modification to do so.

The J8Unit TestClass model provides this indispensable extension just by additionally scanning for all @Test annotated default methods. Unless overridden by a more specific method within the given test class or any of its super classes, these tests will be executed too.

In result, J8Unit allows you to group tests within certain interfaces. Even more, tests can be easily reused independently of a specific test class hierarchy.

The Reusable Tests API

Admittedly, reusing tests does not make sense if the behaviour is absolutely the same each time it is invoked. Doing so would be nothing else than a multiple execution of the same test.

Hence, J8Unit tests usually base on a specific type-under-test and, within each test execution, use an instance of it.

If you are using an existing API (by extending some API classes or implementing sone API interfaces), you should only provide instances of your type-under-test and reuse the accompanying J8Unit-based tests of that API. If you are programming a new API, you should also provide such reusable J8Unit-based tests in order to allow others to verify the conformance of their implementations against your behaviour expectations.

The J8Unit Repository

As a matter of course, every custom Java type must conform to the related Java API and every implementation of a Java interface must conform to the interface’s requirements, usually “specified” as JavaDoc. In general, every overridden method must conform to the requirements of the super type.

In addition, even the classes itself must conform to various expectations.

For example, all sub-types of Throwable should provide a zero-argument and a String-argument constructor. Obviously, this is a class-specific behaviour. In general, all constraints referring to the provision of specific constructors (and its individual requirements) should be covered by according test methods. (Note, this is not limited to constructors only -- Just think of factory methods and further.)

For another example, by virtue of the AnnotationTypeElementDeclaration production, a method declaration in an annotation type declaration cannot have formal parameters, type parameters, or a throws clause (JLS, Sec. 9.6.1). Apparently, this is a type-specific behaviour too; And it must be tested!

Since Java does not provide a J8Unit-based collection of reusable tests, the J8Unit Repository has been created. Currently, it contains more than 8.100 reusable J8Unit skeleton tests classes and few real test methods. In order to make use of these tests, you need to add the J8Unit Repository to your test scope:

<dependency>
  <groupId>org.j8unit</groupId>
  <artifactId>repository</artifactId>
  <version>1.0.0</version>
  <scope>test</scope>
</dependency>

The J8Unit Test Runners

Unfortunately, JUnit4 does not provide injection of the test class model to be used; Thus, when running J8Unit tests you have to specify an according test runner that is aware of the extended J8Unit TestClass model.

J8Unit provides such runners for each common use case:

  • for single test classes (J8BlockJUnit4ClassRunner, J8Unit4),
  • for parameterised tests (J8Parameterized),
  • for Spring projects (J8UnitSpringJUnit4ClassRunner, J8UnitSpringRunner),
  • for an automatic invocation of all suitable J8Unit tests that are provided by the J8Unit Repository and similar repositories (APIConformance).

In order to make use of these test runners, you need to add J8Unit Core to your test scope:

<dependency>
  <groupId>org.j8unit</groupId>
  <artifactId>core</artifactId>
  <version>4.12.1<version>
  <scope>test</scope>
</dependency>

To emphasise the last point again: APIConformance automatically invokes all suitable J8Unit tests. We strongly recommend to consider the usage of this test runner. Really! Give it a try ... You will love the superduper combination with the J8Unit Repository.

Additional Assert Methods

The current JUnit4 Assert statements are strongly coupled to String-based messages.

However, you might want to provide CharSequence-based messages. Or even further, you might want to use the Java 8’s Supplier to provide on-demand messages. (Such intention is similar to this or this.)

The J8Unit Assert provides these additional assert methods. Similar to the J8Unit runners, you need to add J8Unit Core to your test scope to use these assertion methods:

<dependency>
  <groupId>org.j8unit</groupId>
  <artifactId>core</artifactId>
  <version>4.12.1<version>
  <scope>test</scope>
</dependency>

Roadmap

See the open issues for a list of proposed features (and known issues).

About

Enhancement for JUnit to take advantage of Java 8

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 100.0%