Skip to content

Replace junit-dataprovider with junit-jupiter-params#1655

Open
hankem wants to merge 11 commits into
mainfrom
replace-junit-dataprovider
Open

Replace junit-dataprovider with junit-jupiter-params#1655
hankem wants to merge 11 commits into
mainfrom
replace-junit-dataprovider

Conversation

@hankem

@hankem hankem commented Jul 6, 2026

Copy link
Copy Markdown
Member

Resolves #1471

hankem added 9 commits July 6, 2026 14:29
…nit-dataprovider dependency

Signed-off-by: Manfred Hanke <Manfred.Hanke@tngtech.com>
…Value}Source

Note that
> By default, `@CsvSource` uses a single quote (') as its quote character [...]
> An empty, quoted value ('') results in an empty String [...]
> whereas an entirely empty value is interpreted as a null reference.
[https://junit.org/junit5/docs/current/api/org.junit.jupiter.params/org/junit/jupiter/params/provider/CsvSource.html]

Signed-off-by: Manfred Hanke <Manfred.Hanke@tngtech.com>
…dSource

For convenience (and to keep the diff smaller)
`com.tngtech.archunit.testutil.DataProviders.$` provides the same API for `junit-jupiter-params`
as `com.tngtech.java.junit.dataprovider.DataProviders.$` did for `junit-dataprovider`.

Signed-off-by: Manfred Hanke <Manfred.Hanke@tngtech.com>
…it-jupiter-params

Signed-off-by: Manfred Hanke <Manfred.Hanke@tngtech.com>
…unit-jupiter-params

Signed-off-by: Manfred Hanke <Manfred.Hanke@tngtech.com>
replacing the JUnit 4 `@Rule`s with JUnit Jupiter extensions,
and also converting some other tests that made use of the same `TestRule`s to JUnit 5
to eliminate these custom `TestRule`s already

Signed-off-by: Manfred Hanke <manfred.hanke@tngtech.com>
Signed-off-by: Manfred Hanke <manfred.hanke@tngtech.com>
…piter-params

Signed-off-by: Manfred Hanke <manfred.hanke@tngtech.com>
Signed-off-by: Manfred Hanke <Manfred.Hanke@tngtech.com>
Signed-off-by: Stefan Gräber <stefan.graeber@tngtech.com>
Signed-off-by: Stefan Gräber <stefan.graeber@tngtech.com>
@Test
@DataProvider(splitBy = "\\|", value = {
@ParameterizedTest
@CsvSource(delimiter = '|', value = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this really hard to read.
I pushed you a commit on top of the chain which migrates this to a MethodSource

return $$(
static Stream<Arguments> be_records() {
return Stream.of(
$(classes().should().beRecords(), SomeRecord.class, String.class),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's get rid of the $ syntax and switch to standard junit 5 methods.
You already made this an alias for Arguments.of which is an alias for Arguments.arguments which is realy nice to read with a static import.
The is also Arguments.argumentSet which has an additional parameter in the front which is used as name of the text.
Since I'm a big fan of the latter one, I would use it in all places which benefit from a custom test name (I haven't spotted one currently using a custom test name)
I pushed you a commit which replaces the $ method with arguments.
If you like it, keep or squash it into yours, otherwise you can also drop it (and please tell me what and why you dislike)

public static Object[][] ORed_conditions() {
return $$(
$(classes()
static Stream<ArchRule> ORed_conditions() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was it intentional to no wrap into Arguments?
I didn't know that that wrapping is optional and always used it so far

List<Object[]> includeMainFolderInput = new ArrayList<>();
List<Object[]> includeTestFolderInput = new ArrayList<>();
static Stream<Arguments> test_location_predicates_and_expected_folder_patterns() {
Set<Arguments> includeMainFolderInput = new HashSet<>();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using any object in a Set requires proper implementations of hashCode and equals.
since Arguments is implemented as functional interface, I think it has just the default implementation of it.
I think it is safer to stay with List<Arguments>. this also gives a deterministic test case order, which I consider desirable (we also had it before)

@Rule
public final ArchConfigurationRule configurationRule = new ArchConfigurationRule();
@RegisterExtension
ArchConfigurationExtension archConfiguration = new ArchConfigurationExtension();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional: include in the commit message the migration ArchConfigurationRule -> ArchConfigurationExtension
I know that it must be done because of junit4 ->junit5 but I think it wouldn't hurt to make it explicit

you even created that Extension in this commit! 🙂
I think that's worth a mention

import org.junit.rules.ExternalResource;

/**
* @deprecated use JUnit 5 and {@link ArchConfigurationExtension} instead

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it feasible to entirely remove this Rule?
I might give it a try later, there seem to be only 25 tests left

public final OutsideOfClassPathRule outsideOfClassPathRule = new OutsideOfClassPathRule();
@Rule
public final ContextClassLoaderRule contextClassLoaderRule = new ContextClassLoaderRule();
@RegisterExtension

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 of these extensions are never accessed as fields in this class (and all are created with default constructor).
any reason why they are not used via @RegisterExtension({ArchConfigurationExtension.class, ContextClassLoaderExtension.class})?

@@ -56,7 +56,7 @@ public void locations_of_packages_within_JAR_URIs() throws Exception {
Set<Location> locations = Locations.ofPackage("org.junit");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you replace this string by org.junit.jupiter.api you can replace org.junit.Test.class by Test.class
I see no reason to use the junit4 variant of it.
let's break that dependency (there are 3 more usages in this class of the class literal)

import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

public class ContextClassLoaderExtension implements BeforeEachCallback, AfterEachCallback {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please deprecate ContextClassLoaderRule

import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

public class SystemPropertiesExtension implements BeforeEachCallback, AfterEachCallback {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please deprecate SystemPropertiesRule

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants