Open
Description
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: testcontainers/testcontainers-java#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.
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 #1020
Metadata
Metadata
Assignees
Labels
No labels