question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Validate actual rule object instead of Field#type for @Rule

See original GitHub issue

Currently, JUnit validates field’s type, and it wants the declaration to implement TestRule.

Is there a reason for that? What if JUnit4 validated the actual value rather than field type?

The validation makes it harder to implement code that supports both JUnit4 and JUnit5.

Sample issue: https://github.com/testcontainers/testcontainers-java/issues/970 (/cc @bsideup, @baev)

TL;DR: Testcontainers has to implement junit4-specific interfaces in Testcontainers APIs, thus Testcontainers forces everybody to have JUnit4 on the classpath which is sad.

https://github.com/testcontainers/testcontainers-java/blob/aa273b5c0136d8bf8d9eb308040b30006ad98144/core/src/main/java/org/testcontainers/containers/Network.java#L20

public interface Network extends AutoCloseable, TestRule { // <-- it would be so much better to be able to remove TestRule here
...

However, if Network extends TestRule is replaced with NetworkImpl implements Network, TestRule, then JUnit4 fails as follows:

@RunWith(Enclosed.class)
public class NetworkTest {

    public static class WithRules {

        @Rule
        public Network network = newNetwork();
Gradle Test Executor 1 > org.testcontainers.containers.NetworkTest > org.testcontainers.containers.NetworkTest$WithRules.initializationError FAILED
    org.junit.runners.model.InvalidTestClassError: Invalid test class 'org.testcontainers.containers.NetworkTest$WithRules':
      1. The @Rule 'network' must implement MethodRule or TestRule.
        at org.junit.runners.ParentRunner.validate(ParentRunner.java:525)
        at org.junit.runners.ParentRunner.<init>(ParentRunner.java:102)
        at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:84)
        at org.junit.runners.JUnit4.<init>(JUnit4.java:23)
        at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
        at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
        at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:125)
        at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:111)
        at org.junit.runners.Suite.<init>(Suite.java:102)
        at org.junit.experimental.runners.Enclosed.<init>(Enclosed.java:31)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:107)
        at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
        at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
        at org.junit.internal.requests.ClassRequest.createRunner(ClassRequest.java:28)
        at org.junit.internal.requests.MemoizingRequest.getRunner(MemoizingRequest.java:19)
        at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:78)
        at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
        at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
        at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
        at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)

See also https://github.com/junit-team/junit4/pull/1020

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:2
  • Comments:22 (14 by maintainers)

github_iconTop GitHub Comments

2reactions
marcphilippcommented, Oct 18, 2021

@panchenko What I meant was sth. along these lines:

JUnit 4

public class SomeTests {

    @Rule TestRule rule = new TestcontainersRule();

    Network network = new Network();

	GenericContainer container = new GenericContainer(...);

	@Test public void test() { ... }
}

JUnit Jupiter

@ExtendWith(TestcontainersExtension.class)
public class SomeTests {

    Network network = new Network();

	GenericContainer container = new GenericContainer(...);

	@Test public void test() { ... }
}
1reaction
marcphilippcommented, Oct 18, 2021

There are certainly some details to be worked out which is why I tried to “summon” @bsideup and @rnorth above.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Validation Rules Fields - Salesforce Help
... Validation Rules · About Field Sets · Build Cross-Object Formulas in the Advanced Formula Tab · Converting a Text Field Type to...
Read more >
firestore security rules / check field type in nested object
Changing the rules to this works for me: function isInteger(fieldName) { return request.resource.data.userBirthTime.
Read more >
7 Defining Validation and Business Rules Declaratively
The easiest way to create and manage validation rules is through declarative validation rules. Declarative validation rules are defined using the overview ...
Read more >
Validation Rules — Cerberus is a lightweight and extensible ...
This can be used in conjunction with the schema rule when validating a mapping in order to set the allow_unknown property of the...
Read more >
VWFieldType (Process API Documentation) - IBM
Use this class to determine the data field types available in a workflow. You can validate a field type value or validate and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found