Migrating to JUnit 5
-
Upload
rafael-winterhalter -
Category
Technology
-
view
180 -
download
0
Transcript of Migrating to JUnit 5
Migrating toJUnit 5 (alpha)
JUnit 4 JUnit 5
import org.junit.Test;
public class JUnit4Test { @Test public void aJunit4TestCase() { // write test here } }
import org.junit.gen5.api.Test;
class JUnit5Test { @Test void aJunit5TestCase() { // write test here } }
public @interface Test { Class<? extends Throwable> expected() default None.class; long timeout() default 0L; }
JUnit 4 JUnit 5
public @interface Test {
}
public @interface Before {}public @interface After {}
public @interface BeforeEach {}public @interface AfterEach {}
public @interface BeforeClass {}public @interface AfterClass {}
public @interface BeforeAll {}public @interface AfterAll {}
public @interface Ignore { String value() default "";}
public @interface Disabled { String value() default "";}
class FunctionalAssertionsWithHamcrest {
@Test void testProcedural() { File file = new File("/some/property.file"); assertTrue(file.exists()); }
@Test void testFunctional() { File file = new File("/some/property.file"); assertTrue(file::exists); }
@Test void testFunctionalGrouped() { File file = new File("/some/property.file"); assertAll(() -> file.canWrite(), () -> file.canRead()); } }
class AssumptionsAndExceptions {
@Test void testFullyConditional() { File file = new File("/some/property.file"); assumeTrue(file.exists()); runSomeRoutineDependingOn(file); }
@Test void testPartlyConditional() { File file = new File("/some/property.file"); assumingThat(file.exists()), () -> { runSomeRoutineDependingOn(file); }); }
@Test void testThrowsExcption() { IOException exception = expectThrows(IOException.class, () -> { new File("?").getCanonicalPath(); }); validate(exception); } }
JUnit 4 JUnit 5
public class ATest { @Test public void foo() {} }
public class BTest { @Test public void bar() {} }
@RunWith(Suite.class) @Suite.SuiteClasses({ ATest.class, BTest.class}) public class MySuite {}
@Tag(SuiteA.class) public class ATest { @Test public void foo() {} }
@Tags( @Tag(SuiteA.class), @Tag(SuiteB.class) )public class BTest { @Test public void bar() {} }
JUnit 4 JUnit 5
public class ATest { @Test public void foo() {} }
public class BTest { @Test public void bar() {} }
@RunWith(Suite.class) @Suite.SuiteClasses({ ATest.class, BTest.class}) public class MySuite {}
@Tag(SuiteA.class) public class ATest { @Test public void foo() {} }
@Tag(SuiteA.class) @Tag(SuiteB.class) @Retention(RUNTIME)public @interface Meta {}
@Metapublic class BTest { @Test public void bar() {} }
@DisplayName("A stack") class TestingAStack { Stack<Object> stack = new Stack<Object>();
@Test @DisplayName("is empty") void isEmpty() { Assertions.assertTrue(stack.isEmpty()); }
@Nested @DisplayName("after pushing an element") class AfterPushing {
String anElement = "an element";
@BeforeEach void init() { stack.push(anElement); }
@Test @DisplayName("it is no longer empty") void isEmpty() { Assertions.assertFalse(stack.isEmpty()); } @Test @DisplayName("returns the element when popped") void returnElementWhenPopped() { Assertions.assertEquals(anElement, stack.pop()); } }}
class DependencyInjection {
@Test void testSelfAware(TestInfo testInfo) { String name = testInfo.getName(); assertTrue("selfAwareTest", name); }}
public interface TestInfo { String getName(); String getDisplayName(); Set<String> getTags(); }
class DependencyInjection {
@Test void testSelfReport(TestReporter testReporter) { long start = System.nanoTime(); doHeavyLifting(); testReporter.publishEntry("time", System.nanoTime() - start); }}
public interface TestReporter { void publishEntry(String key, String value); void publishEntry(Map<String, String> values);}
JUnit 4 JUnit 5
public @interface Rule { String value() default "";}public @interface RunWith { Class<? extends Runner> value(); }
public @interface ExtendWith { Class<? extends Extension>[] value(); }
interface ContainerExecutionCondition {...} interface TestExecutionCondition { ... }
interface BeforeAllExtensionPoint { ... } interface BeforeEachExtensionPoint { ... } interface InstancePostProcessor { ... } interface MethodParameterResolver { ... }
interface ExceptionHandlerExtensionPoint { ... } interface AfterEachExtensionPoint { ... } interface AfterAllExtensionPoint { ... }
@ExtendWith(FooExtension.class)class FunctionalAssertionsWithHamcrest {
@Test void testProcedural(@Foo File file) { assertTrue(file.exists()); }}
@Retention(RUNTIME) @interface Foo {}
class FooExtension implements MethodParameterResolver {
@Override public boolean supports(Parameter parameter, MethodInvocationContext methodInvocationContext, ExtensionContext extensionContext) { return parameter.isAnnotationPresent(Foo.class); }
@Override public Object resolve(Parameter parameter, MethodInvocationContext methodInvocationContext, ExtensionContext extensionContext){ return new File("some/file"); } }
Currently still unsupported:1. Parameterized tests (no test-runner equivalent)2. No test-timeout3. No sorting of test methods
JInit 5 is work-in-progress and the development has sloweddown significantly. Tickets for M1 are up-for-grab on GitHub!
http://rafael.codes@rafaelcodes
http://documents4j.comhttps://github.com/documents4j/documents4j
http://bytebuddy.nethttps://github.com/raphw/byte-buddy