Mockito и правильное сопоставление varargs с перегруженными методами с Spring Redis

У меня есть следующий метод в моей службе.

private final ReactiveRedisTemplate<String, String> reactiveRedisTemplate;
public Mono<Boolean> deleteObject(String... keys) {
    return reactiveRedisTemplate.delete(keys).map(c -> c > 0);
}

ReactiveRedisTemplate имеет две внутренние реализации для удаления с разными подписями.

@SafeVarargs
public final Mono<Long> delete(K... keys) {
    Assert.notNull(keys, "Keys must not be null!");
    Assert.notEmpty(keys, "Keys must not be empty!");
    Assert.noNullElements(keys, "Keys must not contain null elements!");
    if (keys.length == 1) {
    ...


public Mono<Long> delete(Publisher<K> keys) {
    Assert.notNull(keys, "Keys must not be null!");
    return this.doCreateFlux((connection) -> {

Теперь, когда у меня есть следующее

var key = "key";
when(reactiveRedisTemplate.delete(key)).thenReturn(Mono.just(1L));
StepVerifier.create(service.removeObject(key))
            .expectNextMatches(c -> c)
            .verifyComplete();
verify(this.reactiveRedisTemplate, times(1)).delete(key);

Я получаю сообщение об ошибке NullPointerException, поэтому похоже, что varargs не совпадают. С ArgumentMatcher получается следующее:

when(reactiveRedisTemplate.delete(ArgumentMatchers.<String>any())).thenReturn(Mono.just(1L));
=> java.lang.IllegalArgumentException: Keys must not contain null elements!

when(reactiveRedisTemplate.delete(eq(new String[] { key }))).thenReturn(Mono.just(1L));
=> java.lang.IllegalArgumentException: Keys must not be null!

when(reactiveRedisTemplate.delete(anyString())).thenReturn(Mono.just(1L));
=> java.lang.NullPointerException (doesn't seem to match)

наконец, пользовательский сопоставитель:

public class StringVarargsMatcher implements VarargMatcher, ArgumentMatcher<String[]> {
    private String[] expectedValues;

    public StringVarargsMatcher(String... expectedValues) {
        Arrays.sort(expectedValues);
        this.expectedValues = expectedValues;
    }

    @Override
    public boolean matches(String[] strings) {
        Arrays.sort(strings);
        return Arrays.equals(strings, expectedValues);
    }
}
when(reactiveRedisTemplate.delete(argThat(new StringVarargsMatcher(key)))).thenReturn(Mono.just(1L));
=> java.lang.IllegalArgumentException: Keys must not be null!

Есть ли способ преодолеть это, чтобы я мог имитировать удаление из ReactiveRedisTemplate и выполнить здесь модульный тест?

Используете ли вы встроенный макет?

Lesiak 23.11.2022 20:16

Нет, я не использую встроенный mock maker.

mpartan 24.11.2022 08:07
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
116
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не издеваетесь над public final Mono<Long> delete(K... keys), так как это окончательный метод, и вы не используете встроенный создатель макетов (как обсуждалось в комментариях).

Как следствие, вызывается реальный метод.

Фабричные методы ArgumentMatcher, такие как any()

  • зарегистрировать счетчик во внутреннем состоянии Mockitos
  • вернуть ноль

Объедините это с вызовом реального метода - вы получите ошибки в утверждениях, сделанных реальным методом.

См.: Насмешки над финальными типами, перечислениями и финальными методами

Другие вопросы по теме