Как захватить ApplicatonEvent в тесте интеграции загрузки Spring? - PullRequest
2 голосов
/ 25 февраля 2020

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

Я хочу перехватить загрузочный тест ApplicationEvent in Spring (не хочу проводить модульное тестирование). Моя цель - записать это событие приложения, а затем выполнить несколько задач в моем тесте, чтобы проверить сквозную функциональность. Поскольку событие не регистрируется в тестовом примере, поэтому я не могу написать интеграционные тесты.

Пожалуйста, дайте мне знать, что не так с кодом.

Спасибо всем.

package com.example.demo;

import org.springframework.context.ApplicationEvent;

public class CacheRefreshEvent extends ApplicationEvent {
    private String message;

    private static final long serialVersionUID = 1L;

    public CacheRefreshEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}
package com.example.demo;

import org.springframework.context.ApplicationEvent;

public class CacheRefreshCompleteEvent extends ApplicationEvent {
    private String message;

    private static final long serialVersionUID = 1L;

    public CacheRefreshCompleteEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}
package com.example.demo;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class CaptureCacheRefreshCompleteEvent implements ApplicationListener<CacheRefreshCompleteEvent> {

    private ApplicationEventPublisher applicationEventPublisher;

    void applicationEvent() throws InterruptedException {
        applicationEventPublisher.publishEvent(new CacheRefreshEvent(this, "event triggered from SolrUtilitiesTest()"));
        Thread.sleep(5000);
        System.out.println("Finished execution of test.");
    }

    public void onApplicationEvent(CacheRefreshCompleteEvent cs) {
        System.out.println("gotcha in CaptureCachedRefreshCompleteEvent");
    }

    public void setApplicationEventPublisher(ApplicationEventPublisher arg0) {
        this.applicationEventPublisher = arg0;
    }

}

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}
package com.example.demo;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@DirtiesContext
@SpringBootTest
class DemoApplicationTests implements ApplicationEventPublisherAware, ApplicationListener<CacheRefreshCompleteEvent> {

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @Test
    void applicationEvent() throws InterruptedException {
        applicationEventPublisher.publishEvent(new CacheRefreshEvent(this, "event triggered from Springboot test"));
        for(int i=0; i< 20; i ++) {
            Thread.sleep(1000);
        }
        System.out.println("Finished execution of test.");
    }

    public void onApplicationEvent(CacheRefreshCompleteEvent cs) {
        System.out.println("gotcha");
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher arg0) {
        this.applicationEventPublisher = arg0;
    }

}

1 Ответ

0 голосов
/ 26 февраля 2020

Одним из способов может быть создание очень простого слушателя с @TestComponent в вашем тесте и автоматическое связывание его как @MockBean.

Подтверждение концепции (протестировано с Spring Boot 2.2 и 2.1):

@SpringBootTest
public class PublishTest {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @MockBean
    private Consumer consumer;

    @Test
    public void test() {
        applicationEventPublisher.publishEvent(new TestEvent(this));

        // events are synchronous by default

        verify(consumer).consumeEvent(any(TestEvent.class));
    }

    @TestComponent
    private static class Consumer {
        @EventListener
        public void consumeEvent(TestEvent testEvent) {
        }
    }

    private static class TestEvent extends ApplicationEvent {
        public TestEvent(Object source) {
            super(source);
        }
    }
}

...