将SpringBoot测试结果中与ApplicationContextRunner的Mock依赖关系转换为Unsatis



我有下面的类,它发布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测试。你嘲笑你的CustomLoggerSpringApplication。现在,您可以发布一个ApplicationReadyEvent,并验证您的侦听器是否已经调用了CustomLogger

最新更新