Spring: Register a component within a test class

时间:2018-08-22 14:00:02

标签: spring-boot spring-test

I am registering an ErrorHandler for my Spring Scheduler and would like to test that is is correctly registered in a SpringTest

So far I have tried:

Handler

@Component
public class ScheduledErrorHandler implements ErrorHandler {
    @Autowired
    private ErrorService errorService;

    @Override
    public void handleError(final Throwable t) {
        errorService.handle(t);
    }

}

Registering the Handler

@EnableScheduling
@Configuration
public class SchedulingConfiguration implements SchedulingConfigurer { 

    @Autowired
    private ScheduledErrorHandler handler;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(1);
        scheduler.setErrorHandler(handler);
        scheduler.initialize();
        taskRegistrar.setScheduler(scheduler);
    }

    //...
}

Testing it's registered

@ContextConfiguration(classes = {
    SchedulerConfiguration.class,
    SchedulerErrorHandler.class
})
@RunWith(SpringRunner.class)
public class SchedulerErrorHandlerTest {

    @MockBean
    private ErrorService service;

    @Autowired
    private ExampleScheduledJob job;

    @Test
    public void verifyHandlerGetsCalled() {
        // Wait until the job runs
        if(!job.latch.await(5, SECONDS)) {
            fail("Job never ran");
        }

        verify(service).handle(any(RuntimeException.class));
    }

    @Component
    public static class ExampleScheduledJob {
        private final CountDownLatch latch = new CountDownLatch(1);

        @Scheduled(fixedRate=1000)
        public void run() {
            latch.countDown();
            throw new RuntimeException("error");
        }
    }
}

However when I do this I get a DependencyNotFound error saying Spring cannot create my test class as no Bean named ExampleScheduledJob can be found. How can I register it only for the sake of this test?

Error creating bean with name 'com.example.demo.SchedulerErrorHandlerTest': Unsatisfied dependency expressed through field 'job'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.SchedulerErrorHandlerTest$ExampleScheduledJob' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

1 个答案:

答案 0 :(得分:3)

这应该有效

@ContextConfiguration(classes = {
        SchedulingConfiguration.class,
        SchedulerErrorHandlerTest.ExampleScheduledJob.class,
        ScheduledErrorHandler.class
})
@RunWith(SpringRunner.class)

您可以如上所述注册您的测试配置类(ExampleScheduledJob)。由于它是静态内部类,因此您需要像SchedulerErrorHandlerTest.ExampleScheduledJob

那样使用它