Common updates from JUnit 4 to JUnit 5 - neighbourhoodie/logging-log4j2 GitHub Wiki
https://www.baeldung.com/junit-5-migration
Make sure the imports are added as static
.
For example:
import static org.junit.jupiter.api.Assertions.assertTrue;
@Test
remains the same. However instead of org.junit.Test
you now use:
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");
Import: import org.junit.jupiter.api.BeforeEach
Replace @Before
with @BeforeEach
Import: import org.junit.jupiter.api.BeforeAll
Replace @BeforeClass
with @BeforeAll
Import: import org.junit.jupiter.api.AfterEach
Replace @After
with @AfterEach
Import: import org.junit.jupiter.api.AfterAll
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@Test
as@ParameterizedTest
will cover that. - Instead of
@Parameterized.Parameters
, use@MethodSource
to 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
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
@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.
@Named
is 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)
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.