Test interfaces

In JUnit 5, there are different rules relative to the use of annotations in Java interfaces. First of all, we need to be aware that @Test, @TestFactory, @BeforeEach, and @AfterEach can be declared on interface default methods.

Default methods is a feature of Java introduced in version 8. These methods (declared using the reserve keyword default) allows to define a default implementation for a given method within a Java interface. This capability can be useful for backward compatibility with existing interfaces.

The second rule regarding JUnit 5 and interfaces is that @BeforeAll and @AfterAll can be declared on static methods in a test interface. Moreover, if the test class, which implements a given interface, is annotated with @TestInstance(Lifecycle.PER_CLASS), the methods @BeforeAll and @AfterAll declared on the interface do not need to be static, but default methods.

The third and final rule concerning interfaces in JUnit 5 is @ExtendWith and @Tag can be declared on test interfaces to configure extensions and tags.

Let's see some simple examples. In the following class, we are creating an interface, not a class. In this interface, we use the annotations @BeforeAll, @AfterAll, @BeforeEach, and @AfterEach. On the one hand, we define @BeforeAll, @AfterAll as static methods. On the other hand, we are defining @BeforeEach and @AfterEach as Java 8 default methods:

package io.github.bonigarcia;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public interface TestLifecycleLogger {

static final Logger log = LoggerFactory
.getLogger(TestLifecycleLogger.class.getName());

@BeforeAll
static void beforeAllTests() {
log.info("beforeAllTests");
}

@AfterAll
static void afterAllTests() {
log.info("afterAllTests");
}

@BeforeEach
default void beforeEachTest(TestInfo testInfo) {
log.info("About to execute {}", testInfo.getDisplayName());
}

@AfterEach
default void afterEachTest(TestInfo testInfo) {
log.info("Finished executing {}", testInfo.getDisplayName());
}

}
We are using the library Simple Logging Facade for Java (SLF4J) in this example. Take a look at the code on GitHub (https://github.com/bonigarcia/mastering-junit5) for details on the declaration of dependencies.

In this example, we are using the annotation TestFactory to define a default method in a Java interface:

package io.github.bonigarcia;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;

import java.util.Arrays;
import java.util.Collection;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;

interface TestInterfaceDynamicTestsDemo {

@TestFactory
default Collection<DynamicTest> dynamicTestsFromCollection() {
return Arrays.asList(
dynamicTest("1st dynamic test in test interface",
() -> assertTrue(true)),
dynamicTest("2nd dynamic test in test interface",
() -> assertTrue(true)));
}

}

Finally, we use the annotation @Tag and @ExtendWith in another interface:

package io.github.bonigarcia;

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.extension.ExtendWith;

@Tag("timed")
@ExtendWith(TimingExtension.class)
public interface TimeExecutionLogger {
}

All in all, we can use these interfaces in our Jupiter tests:

package io.github.bonigarcia;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

class TestInterfaceTest implements TestLifecycleLogger,
TimeExecutionLogger,
TestInterfaceDynamicTestsDemo {

@Test
void isEqualValue() {
assertEquals(1, 1);
}

}

In this test, the fact of implementing all the previously defined interfaces will provide the logging capabilities implemented in the default methods:

Console output of test implementing several interfaces
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.173.199