Отключить @EnableScheduling на Spring Тесты
Когда я запускаю свои модульные тесты, он вызывает мои запланированные задачи. Я хочу предотвратить это поведение, вызванное тем, что у меня есть @EnableScheduling
в моей основной конфигурации приложения.
Как я могу отключить это на своих модульных тестах?
Я столкнулся с этим вопросом/ответом, который предлагает настроить профили?
Не знаете, как я буду это делать? или если это перебор? Я думал о том, чтобы иметь отдельную конфигурацию AppConfiguration для своих модульных тестов, но мне кажется, что я повторяю код дважды, когда я это делаю?
@Configuration
@EnableJpaRepositories(AppConfiguration.DAO_PACKAGE)
@EnableTransactionManagement
@EnableScheduling
@ComponentScan({AppConfiguration.SERVICE_PACKAGE,
AppConfiguration.DAO_PACKAGE,
AppConfiguration.CLIENT_PACKAGE,
AppConfiguration.SCHEDULE_PACKAGE})
public class AppConfiguration {
static final String MAIN_PACKAGE = "com.etc.app-name";
static final String DAO_PACKAGE = "com.etc.app-name.dao";
private static final String ENTITIES_PACKAGE = "com.etc.app-name.entity";
static final String SERVICE_PACKAGE = "com.etc.app-name.service";
static final String CLIENT_PACKAGE = "com.etc.app-name.client";
static final String SCHEDULE_PACKAGE = "com.etc.app-name.scheduling";
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
// stripped code for question readability
}
// more app config code below etc
}
Unit test пример.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={AppConfiguration.class})
@Transactional
@TransactionConfiguration(defaultRollback = true)
@WebAppConfiguration
public class ExampleDaoTest {
@Autowired
ExampleDao exampleDao;
@Test
public void testExampleDao() {
List<Example> items = exampleDao.findAll();
Assert.assertTrue(items.size()>0);
}
}
Ответы
Ответ 1
В каждом тесте вы определяете, какую конфигурацию следует использовать spring, в настоящее время у вас есть:
@ContextConfiguration(classes={AppConfiguration.class})
Обычная практика заключается в определении отдельной конфигурации spring для вашего обычного приложения и для ваших тестов.
AppConfiguration.java
TestConfiguration.java
Затем в вашем тесте вы просто используете TestConfiguration
вместо текущего AppConfiguration
, используя @ContextConfiguration(classes={TestConfiguration.class})
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestConfiguration.class})
@Transactional
@TransactionConfiguration(defaultRollback = true)
@WebAppConfiguration
public class ExampleDaoTest
Таким образом вы можете настроить любые настройки для своих тестов иначе, чем в производственном коде. Например, вы можете использовать базу данных в памяти для своих тестов вместо обычной и многое другое.
Ответ 2
Если вы не хотите использовать профили, вы можете добавить флаг, который будет включать/отключать планирование для приложения
В AppConfiguration
добавить
@ConditionalOnProperty(
value = "app.scheduling.enable", havingValue = "true", matchIfMissing = true
)
@Configuration
@EnableScheduling
public static class SchedulingConfiguration {
}
и в вашем тесте просто добавьте эту аннотацию, чтобы отключить планирование
@TestPropertySource(properties = "app.scheduling.enable=false")
Ответ 3
Альтернативой может быть отмена регистрации пост-процессора bean, который планирует события. Это можно сделать, просто поместив следующий класс в путь к классам ваших тестов:
public class UnregisterScheduledProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (String beanName : beanFactory.getBeanNamesForType(ScheduledAnnotationBeanPostProcessor.class)) {
((DefaultListableBeanFactory)beanFactory).removeBeanDefinition(beanName);
}
}
}
В то время как это довольно просто и, похоже, выполняет эту работу, будьте осторожны, я не тестировал это и не проверял возможные последствия удаления определенного реестра bean из реестра или обеспечения того, что упорядочение PostProcessors не будет проблема...