Использование mokito.когда для метода со строковыми аргументами и аргументами класса

#java #unit-testing #mocking #spring-boot-test

#java #модульное тестирование #издевательство #spring-boot-test

Вопрос:

У меня есть метод, с помощью которого я хотел бы создать некоторый модульный тест (этот метод деформирует

ApplicationContext.getEnvironment().getProperty(ключ, класс)

для интеграции с consul)

Короче говоря:

 public class DynamicProperties {

 public <T> T getEnvironmentProperty(String key, Class<T> cls) {
        return cls.cast(applicationContext.getEnvironment().getProperty(key,cls));
    }
}
  

при тестировании какого-либо другого класса, который использует класс DynamicProperties, в качестве следующего:

    @Test
    void testA() {
        //before
        when(dynamicProperties.getEnvironmentProperty(eq(KEY_A), Boolean.class)).thenReturn(true);
        when(dynamicProperties.getEnvironmentProperty(eq(KEY_B), Long.class)).thenReturn(0l);

        //when
        archivedSensorsService.testMethod();

        //than
        verify(...)
    }
  

KEY_A KEY_B являются общедоступными статическими конечными строками
Я получаю следующую ошибку:

 This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));
  

При попытке выполнить следующее:

  @Test
        void testA() {
            //before
            when(dynamicProperties.getEnvironmentProperty(eq(KEY_A), anyObject())).thenReturn(true);
            when(dynamicProperties.getEnvironmentProperty(eq(KEY_B), anyObject())).thenReturn(0l);
    
            //when
            archivedSensorsService.testMethod();
    
            //than
            verify(...)
        }
  

Получаю следующую ошибку:

 org.mockito.exceptions.misusing.PotentialStubbingProblem: 
Strict stubbing argument mismatch. Please check:
 - this invocation of 'getEnvironmentProperty' method:
    dynamicProperties.getEnvironmentProperty(
    null,
    null
);
    -> at com.xxx.xxx ionNotBeenTriggered(..)
 - has following stubbing(s) with different arguments:
    1. dynamicProperties.getEnvironmentProperty(
    null,
    null
);
  

Есть предложения?

Ответ №1:

Проблема вызвана смешиванием mocking с сопоставителями аргументов и без них. Если вы используете средство сопоставления аргументов с одним из аргументов издевательского метода, вам придется использовать средство сопоставления для всех них. Вы можете прочитать больше здесь.

Я создал простой проект на GitHub с решением — вы можете проверить его, если хотите, но вот фрагмент:

 @Test
void withoutEq() {
    DynamicProperties dynamicProperties = mock(DynamicProperties.class);
    when(dynamicProperties.getEnvironmentProperty(KEY_A, Boolean.class))
            .thenReturn(true);
    when(dynamicProperties.getEnvironmentProperty(KEY_B, Long.class))
            .thenReturn(1L);

    assertAll(
            () -> assertTrue(dynamicProperties.getEnvironmentProperty(KEY_A, Boolean.class)),
            () -> assertEquals(1, dynamicProperties.getEnvironmentProperty(KEY_B, Long.class))
    );
}

@Test
void withEq() {
    DynamicProperties dynamicProperties = mock(DynamicProperties.class);
    when(dynamicProperties.getEnvironmentProperty(eq(KEY_A), eq(Boolean.class)))
            .thenReturn(true);
    when(dynamicProperties.getEnvironmentProperty(eq(KEY_B), eq(Long.class)))
            .thenReturn(1L);

    assertAll(
            () -> assertTrue(dynamicProperties.getEnvironmentProperty(KEY_A, Boolean.class)),
            () -> assertEquals(1, dynamicProperties.getEnvironmentProperty(KEY_B, Long.class))
    );
}
  

Как вы можете видеть, один из методов использует eq сопоставитель для обоих аргументов метода, а другой не использует ни одного. Оба теста пройдены.

В вашем случае

 when(dynamicProperties.getEnvironmentProperty(eq(KEY_A), anyObject())).thenReturn(true);
  

этот макет не вызвал ошибку «сопоставление в сочетании с необработанными значениями», потому что eq и anyObject оба являются сопоставителями аргументов, но

 when(dynamicProperties.getEnvironmentProperty(eq(KEY_A), Boolean.class)).thenReturn(true);
  

имеет средство сопоставления ( eq ) и простой объект ( Boolean.class без eq ).

Комментарии:

1. Хм … не уверен, я вас полностью понял, я использовал тот, что с AnyObject (), я все еще получал ошибку, как я написал в сообщении, можете ли вы уточнить это?

2. Это вызвано многократным пересмотром с помощью средств сопоставления аргументов, которые на самом деле возвращают null (именно так реализован Mockito), если включено строгое заглушение. Вы можете прочитать больше здесь , но в основном, чтобы избежать этой ошибки, вы должны использовать doReturn(...).when(...) вместо этого (как указано в связанных документах).