Contents
  1. 1. Spring如何对ApplicationEventPublisher进行Mock
    1. 1.1. 前言
    2. 1.2. 解决方案
    3. 1.3. 示例代码

Spring如何对ApplicationEventPublisher进行Mock

前言

Spring框架里,ApplicationEventPublisher默认是不能Mock的,因为ApplicationEventPublisher是一个复杂的Bean,不能简单的被Mock,会报错:

Failed to instantiate [org.springframework.context.ApplicationEventPublisher]: Specified class is an interface

GitHub上也有相关的Issue:ApplicationEventPublisher mocked with MockBean is not injected

解决方案

在GitHub上有一个解决方案:Make it possible to mock ApplicationEventPublisher

简单来说,就是构建一个TestConfiguration,启动时注入自定义的Mock publisher。

  1. 创建一个TestConfiguration,覆盖默认的ApplicationEventPublisher:

    @TestConfiguration
    public class MockitoConfiguration {
    
    @Bean
    @Primary
    public ApplicationEventPublisher publisher() {
         return mock(ApplicationEventPublisher.class);
        }
    }
    
  2. 测试类中使用@Import注解引入该配置:

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = PublisherApplication.class)
    @ActiveProfiles("dev")
    @Slf4j
    @Import(MockitoConfiguration.class)
    public class PublisherApplicationTests {
    }
    
  3. 调用被测试方法,进行验证:

    @Test
    public void mock_publisher_ok() {
        MockitoAnnotations.openMocks(this);
    
        service.foo();
    
        verify(publisher).publishEvent(isA(FooEvent.class));
    }
    
  4. 完整代码:

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = PublisherApplication.class)
    @ActiveProfiles("dev")
    @Slf4j
    @Import(MockitoConfiguration.class)
    public class PublisherApplicationTests {
    @Autowired
    @SpyBean
    private ApplicationEventPublisher publisher;
    @Autowired
    private BizService service;
    
    @Test
    public void mock_publisher_ok() {
        MockitoAnnotations.openMocks(this);
    
        service.foo();
    
        verify(publisher).publishEvent(isA(FooEvent.class));
        }
    }
    

示例代码

完整示例代码:Mock publisher

Contents
  1. 1. Spring如何对ApplicationEventPublisher进行Mock
    1. 1.1. 前言
    2. 1.2. 解决方案
    3. 1.3. 示例代码