【问题标题】:How to Capture ApplicatonEvent in Spring boot integration test?如何在 Spring Boot 集成测试中捕获 ApplicatonEvent?
【发布时间】:2020-06-08 20:59:36
【问题描述】:

问题是应用程序事件没有在 Spring 启动测试中被捕获虽然它适用于在应用程序项目中侦听事件的文件。

我想在 Spring 启动测试中捕获一个 ApplicationEvent(不想进行单元测试)。我的目标是捕获此应用程序事件,然后在我的测试中执行一些任务来验证端到端功能。因为,事件没有在测试用例中被捕获,所以我无法编写集成测试。

请告诉我代码有什么问题。

谢谢大家。

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;
    }

}

【问题讨论】:

  • 欢迎来到 StackOverflow。请不要添加链接,但请在您的问题中包含代码。
  • 感谢您的建议,Deinum。你能帮我解决这个问题吗?我实际上想在 DemoApplicationTests.java 的测试用例中捕获“CacheRefreshCompleteEvent”事件。但是它没有在测试中被捕获,而它在像 CaptureCacheRefreshCompleteEvent.java 这样的应用程序包中的类中工作。
  • 您的测试不是 Spring 托管 bean,因此不会注册为事件监听器。
  • 好的,有没有办法在 Spring Boot 测试文件中捕获事件?
  • 嗨,我添加了一个简单 POC 的答案。 - 它应该适用于 Spring Boot 2.1 和 2..2。

标签: spring spring-boot integration-testing


【解决方案1】:

一种方法是在您的测试中使用@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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2016-07-03
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 2020-04-24
    • 2017-10-27
    • 1970-01-01
    • 2019-08-20
    相关资源
    最近更新 更多