当前位置: 首页 > 知识库问答 >
问题:

如何在Spring Boot集成测试中捕获ApplicatonEvent?

越英韶
2023-03-14

问题是在Spring boot测试中没有捕获到应用程序事件,而在应用程序项目中侦听事件的文件可以很好地工作。

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个答案

夏侯智鑫
2023-03-14

一种方法是在测试中使用@testcomponent创建一个非常简单的侦听器,并将其autowire为@mockbean

概念证明(用Spring Boot2.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);
        }
    }
}

 类似资料:
  • 与@mockbean和@spybean一样,有没有类似于@fakebean/@dummybean的东西? 其思想是,该实例是100%真实的(具有预期的生产内部状态),并且它覆盖(或者添加bean,以防在配置中没有声明)上下文中的bean。理想情况下,您不需要创建TestConfiguration类并将其设置为Primary,因为这样可以在每个测试的基础上控制假冒,只有在需要时才可以。否则它使用主的

  • 我想用liquibase变更集进行模拟数据的集成测试,如何使其不影响真实数据库?我从这里找到了部分想法,但我使用的是springboot,我希望有更简单的解决方案。

  • 问题内容: 我有一个Java方法,可在Mongo集合的两个字段上创建索引。我应该获取集合的索引信息,然后检查索引的名称和字段是否正确。为此编写集成测试的最干净方法是什么?使用自定义的Hamcrest匹配器查看索引是否在集合中是否有意义? 问题答案: 在春天 使用,您可以获取的列表,代表MongoDB集合的索引。由于这是一个常规列表,因此您可以结合使用和进行断言: 如果您觉得这太难以理解或不方便使用

  • 我正在使用一个带有spring boot 2.0.0.rc1的多项目分级器。我的子项目之一是SpringBoot应用程序,其中包含了我的集成测试。 集成测试用WebEnvironment.random_port标记为@springboottest。由于未解析的依赖关系(在另一个子项目中声明的服务,的同级),测试失败,使用了gradle命令行,但在Eclipse IDE中成功。 如果有人有主意?如何

  • 我有几个繁重的Spring集成测试(是的,这不是最好的方法,我没有时间正确地模拟所有外部dep) 下面是测试的典型注释 由于以下原因,测试会定期失败: 这里有两个问题:1、让测试共存的正确方式是什么?我在surefire插件中设置了forkCount=0。好像有帮助 2.1. 在每次测试期间,我实际上不需要启动所有的