Skip to content

ParameterizedTestParameterResolver conflicts with parameterized @BeforeEach #833

Closed

Description

Overview

The ParameterizedTestParameterResolver conflicts with parameter resolution in @BeforeEach methods in the class containing the @ParameterizedTest. I would presume that parameterized @BeforeEach methods in super-classes as well as @AfterEach methods will have the same problem.

Bug report

  • JUnit 5 version M4
  • Current behavior: The ParameterizedTestParameterResolver attempts to provide parameter resolution for other methods. My opinion is that the ParameterResolver should make sure it's "injecting" parameters only for methods annotated with @ParameterizedTest.
  • Expected behavior: The parameters provided on a @ParameterizedTest method would only resolve parameters on the annotated test method.

Example

In a class annotated with @ExtendWith(MockitoExtension.class), the following set-up and test methods are present:

  @BeforeEach
  void setUp(@Mock Consul.Builder consulBuilder, @Mock Consul consulClient) {
    doReturn(consulClient).when(consulBuilder).build();
    
    consulKeyInjector = new ConsulKeyInjector();
    consulKeyInjector.consulBuilder = consulBuilder;
    consulKeyInjector.consulClient = consulClient;
  }

  @ParameterizedTest
  @CsvSource({
      "CamelCase, CAMELCASE",
      "dotted.java.property, DOTTED_JAVA_PROPERTY",
      "ALREADY_AN_ENVIRONMENT_VARIABLE, ALREADY_AN_ENVIRONMENT_VARIABLE"
  })
  void testToEnvironmentName(String input, String expected) {
    String actual = ConsulKeyInjector.toEnvironmentName(input);
    assertThat(actual).isEqualTo(expected);
  }

Note that in this case, other @Test methods in this class are actually using the mocks. When this class' tests are executed, the following failure is logged:

testToEnvironmentName(String, String)  Time elapsed: 0.001 sec  <<< FAILURE!
org.junit.jupiter.api.extension.ParameterResolutionException: Discovered multiple competing ParameterResolvers for parameter [com.orbitz.consul.Consul$Builder arg0] in executable [void edu.psu.swe.consul.ConsulKeyInjectorTests.setUp(com.orbitz.consul.Consul$Builder,com.orbitz.consul.Consul)]: edu.psu.swe.consul.MockitoExtension, org.junit.jupiter.params.ParameterizedTestParameterResolver

Work-around

Allow the MockitoExtension's TestInstancePostProcessor to inject the mocks into member fields in the test class as shown below:

  @Mock
  Consul.Builder consulBuilder;
  
  @Mock
  Consul consulClient;
  
  ConsulKeyInjector consulKeyInjector;
  
  @BeforeEach
  void setUp() {
    doReturn(consulClient).when(consulBuilder).build();
    
    consulKeyInjector = new ConsulKeyInjector();
    consulKeyInjector.consulBuilder = consulBuilder;
    consulKeyInjector.consulClient = consulClient;
  }

Deliverables

  • Limit the ParameterizedTestParameterResolver's scope to only the method it's annotating.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions