簡體   English   中英

在 SpringBoot 測試結果中使用 ApplicationContextRunner 模擬依賴項到 UnsatisfiedDependencyException

[英]Mock dependency with ApplicationContextRunner in SpringBoot Test result into UnsatisfiedDependencyException

我關注 class,它發布了 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));
              });
    }

}

到目前為止,這工作正常,因為 class (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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM