Невозможно выполнить модульное тестирование аннотированного метода @KafkaListener. - PullRequest
0 голосов
/ 07 мая 2018

Я пытаюсь провести модульное тестирование класса потребителей kafka весной. Я хочу знать, что, если сообщение kafka отправлено в его тему, метод слушателя был вызван правильно. Мой потребительский класс помечен так:

@KafkaListener(topics = "${kafka.topics.myTopic}")
public void myKafkaMessageEvent(final String message) { ...

Если я @Autowire потребителя, когда я отправляю сообщение kafka, метод слушателя вызывается правильно, но я не могу утверждать, что метод был вызван, потому что класс не фиктивный.

Если я высмеиваю потребителя, когда я отправляю сообщение kafka, метод слушателя вообще не вызывается. Я могу вызвать метод напрямую и утверждать, что он работал, но это не делает то, что я хочу, а именно проверять, вызывается ли метод при отправке сообщения kafka в его тему.

Сейчас я прибегнул к установке счетчика внутри потребителя и увеличивал его при каждом вызове метода слушателя, а затем проверял, что его значение было изменено. Создание переменной только для тестирования кажется мне ужасным решением.

Может быть, есть способ заставить получателя-получателя тоже получать сообщения кафки? Или каким-то другим способом утверждать, что был вызван немодируемый потребительский приемник?

1 Ответ

0 голосов
/ 07 мая 2018

Звучит так, будто вы запрашиваете нечто похожее на то, что есть в Spring AMQP Testing Framework: https://docs.spring.io/spring-amqp/docs/2.0.3.RELEASE/reference/html/_reference.html#test-harness

Итак, если вы не умеете работать с дополнительной переменной, вы можете позаимствовать это решение и реализовать свой собственный "жгут".

Я думаю, что это должно быть хорошим дополнением к Framework, поэтому, пожалуйста, поднимите соответствующий вопрос , и мы вместе сможем создать такой инструмент для общественности.

UPDATE

Итак, согласно фундаменту Spring AMQP, я сделал это в своей тестовой конфигурации:

public static class KafkaListenerTestHarness extends KafkaListenerAnnotationBeanPostProcessor {

    private final Map<String, Object> listeners = new HashMap<>();

    @Override
    protected void processListener(MethodKafkaListenerEndpoint endpoint, KafkaListener kafkaListener,
            Object bean, Object adminTarget, String beanName) {

        bean = Mockito.spy(bean);

        this.listeners.put(kafkaListener.id(), bean);

        super.processListener(endpoint, kafkaListener, bean, adminTarget, beanName);
    }

    @SuppressWarnings("unchecked")
    public <T> T getSpy(String id) {
        return (T) this.listeners.get(id);
    }

}

...

@SuppressWarnings("rawtypes")
@Bean(name = KafkaListenerConfigUtils.KAFKA_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public static KafkaListenerTestHarness kafkaListenerAnnotationBeanPostProcessor() {
    return new KafkaListenerTestHarness();
}

Тогда в целевом тестовом примере я использую его так:

@Autowired
private KafkaListenerTestHarness harness;
...
Listener listener = this.harness.getSpy("foo");

verify(listener, times(2)).listen1("foo");
...