我有下面的类,它发布spring事件。
@Component
public class ApplicationReadyEventListener {
Boolean isHit = false;
@EventListener
public void handle(final ApplicationReadyEvent applicationReadyEvent) {
applicationReadyEvent.getSpringApplication().getClass().toGenericString()));
isHit = true; // This needs to be replaced with CustomLoggerComponent
}
}
由于我需要发布事件并需要检查失败和成功事件,我有以下测试:
@ExtendWith({SpringExtension.class})
class ApplicationReadyEventListenerTest {
private final ApplicationContextRunner runner = new ApplicationContextRunner();
//Success Test
@Test
void loggerShouldLogWhenApplicationIsReady() {
SpringApplciation application = new SpringApplication(ApplicationReadyEventListener.class);
application.setWebApplicationType(WebApplicationType.NONE);
final ApplicationReadyEvent event = new ApplicationReadyEvent(application, null, mock(ConfigurableApplicationContext.class));
runner.withBean(ApplicationReadyEventListener.class)
.run(context -> {
context.publishEvent(event);
final ApplicationReadyEventListener applicationStartedListener = context.getBean(ApplicationReadyEventListener.class);
MatcherAssert.assertThat(applicationStartedListener.isHit(), is(true));
});
}
//FailureTest
@Test
void shouldNotCallApplicationStarted() {
SpringApplciation application = new SpringApplication(ApplicationReadyEventListener.class);
application.setWebApplicationType(WebApplicationType.NONE);
final RuntimeException runtimeException = new RuntimeException("Some Error Occurred");
final ApplicationEvent event = new ApplicationFailedEvent(application, null, mock(ConfigurableApplicationContext.class), runtimeException);
runner.withBean(ApplicationReadyEventListener.class)
.run(context -> {
context.publishEvent(event);
final ApplicationReadyEventListener applicationStartedListener = context.getBean(ApplicationReadyEventListener.class);
MatcherAssert.assertThat(applicationStartedListener.isHit(), is(false));
});
}
}
由于类(ApplicationReadyEventListener(没有任何bean,因此到目前为止,这一切都很正常。我想有一个自定义记录器,而不是isHit,我会检查自定义记录器的方法被调用的副作用。
然而,我无法添加任何依赖项,所以我试图通过创建一个单独的应用程序来隔离问题,该应用程序包含测试中的主题ApplicationReadyEvent
,并创建CustomLoggerBean,使用以下应用程序:
@Configuration
public class CustomLogMockProvider {
@Bean
public Logger logger() {
return Mockito.mock(Logger.class);
}
}
当我为同样的东西写这个测试时:
@Test
void tesCustomLoggerBeanPresence() {
SpringApplciation application = new SpringApplication(CustomLogger.class);
application.setWebApplicationType(WebApplicationType.NONE);
runner.withBean(CustomLogMockProvider.class)
.run(context -> {
String[] beanNamesForType = context.getBeanNamesForType(Logger.class);
Arrays.stream(beanNamesForType).forEach(System.out::println);
});
}
为上面的一个获取UnsatisfiedDependencyException
。
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'applicationReadyEventListener': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.Class] to required type [com.priti.com.common.config.CustomLogger]: Failed to convert value of type 'java.lang.Class' to required type 'com.priti.com.common.config.CustomLogger'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.Class' to required type 'com.priti.com.common.config.CustomLogger': no matching editors or conversion strategy found
这方面的任何线索都会有所帮助。
我认为您的测试设置是个问题。您正在用手工做很多事情,而不是使用适当的Spring工具。
如果你想测试你的ApplicationReadyEventListener
,测试应该是这样的:
@ExtendWith({SpringExtension.class})
@ContextConfiguration(classes = ApplicationReadyEventListener.class)
class ApplicationReadyEventListenerTest {
@MockBean
private SpringApplication springApplicationMock;
@MockBean
private CustomLogger customLoggerMock;
@Autowired
private ApplicationEventPublisher publisher;
@Test
void name() {
publisher.publishEvent(new ApplicationReadyEvent(springApplicationMock, null, null));
verify(customLoggerMock).doSomething();
}
}
您可以使用SpringExtension.class
运行Spring测试。你嘲笑你的CustomLogger
和SpringApplication
。现在,您可以发布一个ApplicationReadyEvent
,并验证您的侦听器是否已经调用了CustomLogger
。