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

在ApplicationEvent上测试Spring的简单方法

璩和璧
2023-03-14

我有一个应用程序事件侦听器,其中包含以下函数:

@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
//do some stuff
}

我如何编写一个单元测试来模拟ContextRefreshedEvent,比如正在执行的jar,并测试我的onApplicationEvent函数是否完成了它应该做的事情?

共有2个答案

戚衡
2023-03-14

我基于这个Spring Boot示例实现了一个编程有效负载侦听器测试,如果有人可能需要模拟测试而不是加载所有Spring上下文。

@Test
public void testProgrammaticEventListener() {
    final List<StoreEvent> events = new ArrayList<>();
    final ApplicationListener<PayloadApplicationEvent<Integer>> listener = forPayload(events::add);

    ConfigurableApplicationContext ac = new GenericApplicationContext();
    ac.addApplicationListener(listener);
    ac.refresh();

    PayloadApplicationEvent<Integer> event = new PayloadApplicationEvent<>(this, 1);
    ac.publishEvent(event);
    assertThat(events.contains(event.getPayload()), Is.is(true));
}

在示例代码中,Application ationListener.forPayload中有一个方法;如果它不存在,您可以手动添加到您的测试类中:

static <T> ApplicationListener<PayloadApplicationEvent<T>> forPayload(final Consumer<T> consumer) {
        return event -> consumer.accept(event.getPayload());
    }

参考PayloadApplication EventTests.java#L65

赵景曜
2023-03-14

这是我能想到的最小的独立示例。

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.concurrent.LinkedBlockingQueue;

import static org.junit.Assert.assertEquals;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RefreshTest.MyConfig.class})
public class RefreshTest {

    @Autowired
    private MyListener listener;

    @Test
    public void test() {
        assertEquals("Refresh should be called once",1, listener.events.size());
    }

    public static class MyConfig {
        @Bean
        public MyListener listener() {
            return new MyListener();
        }
    }

    public static class MyListener implements ApplicationListener <ContextRefreshedEvent> {
        // you don't really need a threadsafe collection in a test, as the test main thread is also loading the spring contest and calling the handler, 
        // but if you are inside an application, you should be aware of which thread is calling in case you want to read the result from another thread. 
        LinkedBlockingQueue<ContextRefreshedEvent> events = new LinkedBlockingQueue<ContextRefreshedEvent>();
        public void onApplicationEvent(ContextRefreshedEvent  event) {
            events.add(event);
        }
    }
}

在处理程序内部测试代码和调用处理程序之间存在差异。不要将代码直接放在处理程序中,而是放在从处理程序调用的另一个bean中,因此可以在没有处理程序的情况下测试逻辑(通过使用您创建的上下文刷新事件调用它)。刷新上下文时(通常在加载上下文时)会发送刷新事件,因此无需对此进行测试。如果在您的生产代码中没有调用它,您通常会立即注意到。此外,测试和生产环境之间的上下文加载可能不同,因此即使您编写了一个显示已调用处理程序的测试,也不能保证它将在生产环境中被调用,除非您使用完全相同的配置运行,我几乎从未这样做,因为我经常使用Profile实现不同的配置/bean,例如,当我不希望我的测试使用AWS队列和其他外部IO通道时。

 类似资料:
  • 问题内容: 我正在自学一些基本的抓取方法,但发现有时输入到代码中的URL返回404,这将困扰我所有的代码。 因此,我需要在代码顶部进行测试,以检查URL是否返回404。 这似乎是一个非常直截了当的任务,但是Google并没有给我任何答案。我担心我在寻找错误的东西。 一个博客建议我使用这个: 然后测试以查看$ valid是否为空。 但是我认为给我带来问题的URL上有一个重定向,因此$ valid对于

  • 虽然这个测试可能是微不足道的,但它说明了单元测试的基本元素。 我们使用解释这个测试是什么,我们使用来断言我们从测试中得到什么样的结果。 这些是用户定义的,因此在这些消息中描述性和准确性是一个好主意。 诸如“应该工作”或“测试服务”之类的消息不能真正解释发生了什么,并且在整个应用程序上运行多个测试时可能会产生混淆。 我们的实际测试是基本的,我们使用制定一个场景,并使用来断言我们从该场景预期的结果条件

  • 我在一个类中设置了一个简单的Spring REST方法,它应该只返回在POST请求中发送给它的文本作为响应。MyService.java类中的My方法: 我有一个单元测试,它使用Spring的MockMvc来测试方法: 415是“内容不受支持”错误。 Spring版本4.1.7。 关于我做错了什么有什么建议吗?提前道谢。

  • import { CounterActions, INCREMENT_COUNTER, DECREMENT_COUNTER, } from './counter'; // Mock out the NgRedux class with just enough to test what we want. class MockRedux extends NgRedux<any> { c

  • Java 8,但这是一个通用的单元测试问题,它(很可能)是与语言无关的。 编写JUnit测试的语法很容易,但是决定要编写什么测试以及如何测试主/生产代码是我发现的最大挑战。在阅读单元测试最佳实践时,我一遍又一遍地听到同样的事情: 测试合同 我相信这个想法是,单元测试不应该是脆弱的,如果方法的实现发生变化,它不应该被破坏。该方法应定义输入的协定 - 假设我有以下方法: 所以在这里,我们有一个方法,我

  • 我试图得到最基本的梯度项目(与测试)建立。我看了所有相关的问题和谷歌搜索,我似乎错过了一些非常基本的,显然不常见的东西。 我创建了一个测试类,“Gradle CompiletestJava”无法编译该文件 就这样。光秃秃的骨头!我还尝试添加 依赖关系{ testCompile'JUnit:JUnit:4.10' 有什么想法吗? 以下是我得到的: