Spring如何对ApplicationEventPublisher进行Mock
Updated:
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。
创建一个
TestConfiguration
,覆盖默认的ApplicationEventPublisher
:@TestConfiguration public class MockitoConfiguration { @Bean @Primary public ApplicationEventPublisher publisher() { return mock(ApplicationEventPublisher.class); } }
测试类中使用@Import注解引入该配置:
@RunWith(SpringRunner.class) @SpringBootTest(classes = PublisherApplication.class) @ActiveProfiles("dev") @Slf4j @Import(MockitoConfiguration.class) public class PublisherApplicationTests { }
调用被测试方法,进行验证:
@Test public void mock_publisher_ok() { MockitoAnnotations.openMocks(this); service.foo(); verify(publisher).publishEvent(isA(FooEvent.class)); }
完整代码:
@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