-
Notifications
You must be signed in to change notification settings - Fork 0
Common updates from JUnit 4 to JUnit 5
https://www.baeldung.com/junit-5-migration
Make sure the imports are added as static.
To all org.junit. imports you have to add jupiter.api like:
import static org.junit.jupiter.api.Assertions.assertTrue;
org.junit.jupiter.api.Test
@Test(expected = UnsupportedOperationException.class) public void ...() { convertToEntity(); }
turns to
import static org.junit.jupiter.api.Assertions.assertThrows;
@Test
public void testConvertToEntityAttribute() {
assertThrows(UnsupportedOperationException.class, () -> this.converter.convertToEntityAttribute(null));
}
Update the import to
org.junit.jupiter.api.Assertions
Note for any assertions with error messages, the message is moved as the second argument.
For example:
// JUnit 4
assertTrue("No messages returned", messages != null && messages.size() > 0);
// JUnit 5
assertTrue(messages != null && messages.size() > 0, "No messages returned");Since JUnit 5 does not directly provide assertThat, we switch to using org.hamcrest.MatcherAssert.assertThat from the hamcrest library.
Replace org.junit.Assert.assertThat with org.hamcrest.MatcherAssert.assertThat
Also import the Matchers:
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.emptyCollectionOf;
import static org.hamcrest.Matchers.hasItemInArray;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.theInstance;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.empty;
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.BeforeAll;
Replace @Before with @BeforeEach
Replace @BeforeClass with @BeforeAll
Replace @After with @AfterEach
Replace @AfterClass with @AfterAll
Remove @Category because JUnit 5 doesn't support categories like JUnit 4. Instead, it uses tags (@Tag), which you can adapt based on your requirements.
Import @Tag like so:
import org.junit.jupiter.api.Tag;
Then use @Tag as follows:
For example: @Category(AsyncLoggers.class) is replaced with @Tag("AsyncLoggers")
Add imports:
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
Replace @RunWith(MockitoJUnitRunner.class) with @ExtendWith(MockitoExtension.class)
- Replace
@RunWith(Parameterized.class)with@ParameterizedTest. Also remove@Testas@ParameterizedTestwill cover that. - Instead of
@Parameterized.Parameters, use@MethodSourceto supply the test parameters - Remove the constructor, as JUnit 5 passes parameters directly to the test methods
- The data() method now returns a Stream<>, which JUnit 5 uses for parameterized tests
Example
// JUnit 5
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
public static Stream<String> data() {
return Stream.of("logger-config/LoggerConfig/", "logger-config/AsyncLoggerConfig/");
}
@ParameterizedTest(name = "{0}")
@MethodSource("data")
// JUnit 4
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import com.google.common.collect.ImmutableList;
import java.util.List;
@RunWith(Parameterized.class)
@Parameterized.Parameters(name = "{0}")
public static List<String> data() throws IOException {
return ImmutableList.of("logger-config/LoggerConfig/", "logger-config/AsyncLoggerConfig/");
}
@Test@ClassRule is deprecated in Junit5 and, unfortunately, the translation is not straight forward. It depends on the implementation. At the moment we have successfully migrated one of is usages in this PR
I'll explain this example:
- Now the class has a new interface
@LoggerContextSource, to which we pass the value of the config file (value = "log4j2-jdbc-dbcp2.xml") and thetimeout(the timeout value is fromLoggerContextRule.createShutdownTimeoutLoggerContextRule) - In the test function, we no longer need to get the appender as it is provided as a parameter of the function.
@Namedis to specify which appender’s name you want to fetch. Before we did it likefinal Appender appender = LCR.getAppender("databaseAppender");, but now (I think) this function is inside the interface@LoggerContextSource, so we only need to specify the appender as a parameter in the test functionpublic void test(@Named("databaseAppender") final Appender appender) {
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
import org.apache.logging.log4j.core.test.junit.Named;
@LoggerContextSource(value = "log4j2-jdbc-dbcp2.xml", timeout = 10)@Rule and @ClassRule no longer exist; superseded by @ExtendWith and @RegisterExtension.
Some of the Rules can be turned into an Extention. James helped with that for the SecurityManagerTestRule and here is the example: https://github.com/neighbourhoodie/logging-log4j2/pull/9/commits/4d0c11afbf480cad2b672f10237d134f0c0aff41
package org.apache.logging.log4j.test.junit;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class SecurityManagerTestRule implements TestRule {
public SecurityManagerTestRule(final SecurityManager securityManager) {
this.securityManager = securityManager;
}
private SecurityManager securityManagerBefore;
private final SecurityManager securityManager;
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
before();
try {
base.evaluate();
} finally {
after();
}
}
private void after() {
System.setSecurityManager(securityManagerBefore);
}
private void before() {
securityManagerBefore = System.getSecurityManager();
System.setSecurityManager(securityManager);
}
};
}
}package org.apache.logging.log4j.test.junit;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
public class SecurityManagerExtension implements BeforeEachCallback, AfterEachCallback {
private SecurityManager securityManagerBefore;
private final SecurityManager securityManager;
public SecurityManagerExtension(final SecurityManager securityManager) {
this.securityManager = securityManager;
}
public void beforeEach(ExtensionContext ctx) {
securityManagerBefore = System.getSecurityManager();
System.setSecurityManager(securityManager);
}
public void afterEach(ExtensionContext ctx) {
System.setSecurityManager(securityManagerBefore);
}
}diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/LoaderUtilSecurityManagerTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/LoaderUtilSecurityManagerTest.java
index beb7cc345b..bb8365a92d 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/LoaderUtilSecurityManagerTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/LoaderUtilSecurityManagerTest.java
@@ -20,15 +20,15 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse;
import java.security.Permission;
-import org.apache.logging.log4j.test.junit.SecurityManagerTestRule;
-import org.junit.Rule;
-import org.junit.Test;
+import org.apache.logging.log4j.test.junit.SecurityManagerExtension;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.ResourceLock;
+import org.junit.jupiter.api.extension.RegisterExtension;
@ResourceLock("java.lang.SecurityManager")
public class LoaderUtilSecurityManagerTest {
- @Rule
- public final SecurityManagerTestRule rule = new SecurityManagerTestRule(new TestSecurityManager());
+ @RegisterExtension
+ public final SecurityManagerExtension ext = new SecurityManagerExtension(new TestSecurityManager());
private static class TestSecurityManager extends SecurityManager {Junit4:
public class ContextStackJsonAttributeConverterTest {
private ContextStackJsonAttributeConverter converter;
@Rule
public final ThreadContextStackRule threadContextRule = new ThreadContextStackRule();
junit5
@UsingThreadContextStack
public class ContextStackJsonAttributeConverterTest {...}
Please update this section when they request changes for the PR we'll do in their side, to reflect the end result they are looking for.