当我运行单元测试时,它会调用我的计划任务。 我想防止这种行为,这是由于我的主应用程序配置中包含@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
}
单元测试示例。
@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);
}
}
spring unit-testing junit junit4 springjunit4classrunner
Robbo_UK asked 2020-08-01T10:36:56Z
5个解决方案
42 votes
如果您不想使用配置文件,则可以添加标志以启用/禁用应用程序调度
在您的AppConfiguration中添加此
@ConditionalOnProperty(
value = "app.scheduling.enable", havingValue = "true", matchIfMissing = true
)
@Configuration
@EnableScheduling
public static class SchedulingConfiguration {
}
在您的测试中,只需添加此注释即可禁用计划
@TestPropertySource(properties = "app.scheduling.enable=false")
Marko Vranjkovic answered 2020-08-01T10:37:24Z
11 votes
另一种选择是取消注册安排事件的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或确保PostProcessor的排序不会成为问题的可能的含义...
yankee answered 2020-08-01T10:37:49Z
9 votes
我只是用可配置的延迟时间参数化了@Scheduled注释:
@Scheduled(fixedRateString = "${timing.updateData}", initialDelayString = "${timing.initialDelay}")
在我的测试application.yaml中:
timing:
updateData: 60000
initialDelay: 10000000000
和主要application.yaml:
timing:
updateData: 60000
initialDelay: 1
它不是关闭它,而是造成了如此长的延迟,测试将在运行之前很长一段时间。 不是最优雅的解决方案,但绝对是我找到的最简单的解决方案之一。
Laila Sharshar answered 2020-08-01T10:38:22Z
2 votes
在每个测试中,您定义应使用的弹簧配置,当前您具有:
@ContextConfiguration(classes={AppConfiguration.class})
常见的做法是为正常应用和测试定义单独的弹簧配置。
AppConfiguration.java
TestConfiguration.java
然后在测试中,您只需使用@ContextConfiguration(classes={TestConfiguration.class})即可引用TestConfiguration,而不是当前的AppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestConfiguration.class})
@Transactional
@TransactionConfiguration(defaultRollback = true)
@WebAppConfiguration
public class ExampleDaoTest
这样,您可以与生产代码中不同的方式为测试配置任何设置。 例如,您可以将内存数据库用于测试,而不是常规数据库。
Vojtech Ruzicka answered 2020-08-01T10:38:56Z
1 votes
通过创建一种在单元测试期间删除计划任务的方法,我能够解决此问题。这是一个例子:
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
import org.springframework.context.ApplicationContext;
public static void removeSchedulledTasks(ScheduledAnnotationBeanPostProcessor postProcessor, ApplicationContext appContext) {
postProcessor.setApplicationContext(appContext);
Iterator<ScheduledTask> iterator = postProcessor.getScheduledTasks().iterator();
while(iterator.hasNext()) {
ScheduledTask taskAtual = iterator.next();
taskAtual.cancel();
}
}
使用示例:
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.example.Utils;
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestRemoveScheduller {
@Autowired
private ScheduledAnnotationBeanPostProcessor postProcessor;
@Autowired
private ApplicationContext appContext;
@Before
public void init(){
//Some init variables
//Remove schedulled tasks method
Utils.removeSchedulledTasks(postProcessor, appContext);
}
//Some test methods
}
希望这可以帮助。
标签:PACKAGE,禁用,app,单元测试,class,AppConfiguration,EnableScheduling,import,public
From: https://blog.51cto.com/u_16110904/6507903