Home > front end >  Junit @ParametrizedTest: use parameters as return values of the mocked object
Junit @ParametrizedTest: use parameters as return values of the mocked object

Time:11-01

I am writing a ParametrizedTest in Junit. The argument for that test is from an enum source.
I want to construct an object with that enum and make the mocked method return that object.
However, when I try to do that, I am getting (what I think is) an irrelevant error message.

org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:  

You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))

Here is the code:

public static enum CodeEnum {
   S1("S1"),
   S2("S2)
}

@RunWith(MockitoJUnitRunner.class)
public class FooTest {
   
   @Mocked
   MockedObject mockedObject;
   
   @InjectMocks
   Foo underTest

   @ParameterizedTest
   @EnumSource(CodeEnum.class)
   public void test_ParametrizedTest(CodeEnum enum) {
      
      Output expectedReturn = Output.builder().code(enum).build();
      
      // Given
      when(mockedObject.method(any()))
          .thenReturn(expectedReturn);
      
      // when 
      val result = underTest.method();
      
      // then
      assertEquas(enum, result.getCode())

   }

}

I suspected that the input should be something other than any() so I created a method that provides data to the test and used a @MethodSource annotation.
That method returns the arguments of the input to the mock and also expectedReturn from the mock.

   @RunWith(MockitoJUnitRunner.class)
   public class FooTest {

      @Mocked
      MockedObject mockedObject;

      @InjectMocks
      Foo underTest

      @ParameterizedTest
      @MethodSource("dataProvider")
      public void test_ParametrizedTest(MockedInput mockedInput, Output expectedReturn) {

         Output expectedReturn = Output.builder().code(enum).build();

         // Given
         when(mockedObject.method(mockedInput))
            .thenReturn(expectedReturn);

        // when 
        val result = underTest.method();

        // then
        assertEquas(enum, result.getCode())

   }
   
   private static Stream<Arguments> dataProvider() {
      return Stream.of(
               Arguments.of(mockedInput1, Output.builder().code(CodeEnum.S1).build()),
               Arguments.of(mockedInput2, Output.builder().code(CodeEnum.S2).build())
      )
   }

}

How to make mocked objects return a parameter from a parametrized test?

CodePudding user response:

The runner I was using was incorrect. I changed it to use MockitoExtension and the tests ran fine.


@ExtendWith(MockitoExtension.class)
public class FooTest {

      @Mocked
      MockedObject mockedObject;

      @InjectMocks
      Foo underTest

      @ParameterizedTest
      @MethodSource("dataProvider")
      public void test_ParametrizedTest(MockedInput mockedInput, Output expectedReturn) {

         Output expectedReturn = Output.builder().code(enum).build();

         // Given
         when(mockedObject.method(mockedInput))
            .thenReturn(expectedReturn);

        // when 
        val result = underTest.method();

        // then
        assertEquas(enum, result.getCode())

   }
   
   private static Stream<Arguments> dataProvider() {
      return Stream.of(
               Arguments.of(mockedInput1, Output.builder().code(CodeEnum.S1).build()),
               Arguments.of(mockedInput2, Output.builder().code(CodeEnum.S2).build())
      )
   }

  • Related