spring 防止 Application / CommandLineRunner 类在 JUnit 测试期间执行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29344313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Prevent Application / CommandLineRunner classes from executing during JUnit testing
提问by Gorgia666
If in your TestCase class there is this annotations:
如果在您的 TestCase 类中有此注释:
@SpringApplicationConfiguration(classes = {Application.class})
this will cause the Application.class
, implementing the CommandLineRunner
interface, to run the required method
这将导致Application.class
,实现CommandLineRunner
接口,运行所需的方法
public void run(String... args) throws Exception
I still think this is, mostly, a not wanted behaviour, since in your test environment you may not want to launch the entire application.
我仍然认为这主要是一种不想要的行为,因为在您的测试环境中,您可能不想启动整个应用程序。
I have in mind two solution to circumvent this problem:
我想到了两种解决方案来规避这个问题:
- to remove the
CommandLineRunner
interface from myApplication
class - to have a different context for testing
CommandLineRunner
从我的Application
班级中删除界面- 有不同的测试环境
Both this solution requires lot of coding. Do you have a more convenient solution?
这两种解决方案都需要大量编码。你有更方便的解决方案吗?
回答by Michael Pridemore
Jan's solution can be achieved easier.
Jan的解决方案可以更容易地实现。
In your test class, activate the "test" profile:
在您的测试类中,激活“测试”配置文件:
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
public class MyFancyTest {}
In your CommandLineRunner set the profile to NOT test:
在您的 CommandLineRunner 中,将配置文件设置为不测试:
@Component
@Profile("!test")
public class JobCommandLineRunner implements CommandLineRunner {}
Then you don't have to manually set the profile in the Application.
然后您不必在应用程序中手动设置配置文件。
回答by jmgonet
As mentioned in spring documentation http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.htmlyou can use @ContextConfigurationwith a special initializer:
正如 spring 文档http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html 中提到的,您可以使用带有特殊初始化程序的@ContextConfiguration:
ConfigFileApplicationContextInitializeris an ApplicationContextInitializerthat can apply to your tests to load Spring Boot application.propertiesfiles. You can use this when you don't need the full features provided by @SpringApplicationConfiguration.
ConfigFileApplicationContextInitializer是一个ApplicationContextInitializer,可以应用于您的测试以加载 Spring Boot application.properties文件。当您不需要@SpringApplicationConfiguration提供的全部功能时,您可以使用它。
In this example anyComponentis initialized and properties are injected, but run(args)methods won't be executed. (Application.classis my main spring entry point)
在此示例中,初始化了anyComponent并注入了属性,但不会执行run(args)方法。(Application.class是我的主要 spring 入口点)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class,
initializers = ConfigFileApplicationContextInitializer.class)
public class ExtractorTest {
@Autowired
AnyComponent anyComponent;
@Test
public void testAnyComponent() {
anyComponent.anyMethod(anyArgument);
}
}
回答by Bogdan Calmac
You can define a test configuration in the same package as your application that looks exactly the same, except that it excludes beans implementing CommandLineRunner. The key here is @ComponentScan.excludeFilters:
您可以在与您的应用程序相同的包中定义一个测试配置,该配置看起来完全相同,只是它不包括实现 CommandLineRunner 的 bean。这里的关键是@ComponentScan.excludeFilters:
@Configuration
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CommandLineRunner.class))
@EnableAutoConfiguration
public class TestApplicationConfiguration {
}
Then, just replace the configuration on your test:
然后,只需替换测试中的配置:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestApplicationConfiguration.class)
public class SomeApplicationTest {
...
}
No CommandLineRunner will be executed now, because they are not part of the configuration.
现在不会执行 CommandLineRunner,因为它们不是配置的一部分。
回答by jihor
I'm a bit late to the party, but a reasonable approach is to mark the bean with @ConditionalOnProperty
, e.g.
我参加聚会有点晚了,但合理的方法是用 标记 bean @ConditionalOnProperty
,例如
@ConditionalOnProperty(prefix = "job.autorun", name = "enabled", havingValue = "true", matchIfMissing = true)
public CommandLineRunner myRunner() {...}
The following annotation will then disable it in tests:
以下注释将在测试中禁用它:
@SpringBootTest(properties = {"job.autorun.enabled=false"})
回答by McAviti
If you have a mocking framework installed (e.g. MockMVC) you can create a mock instance of the CommandLineRunner implementation, more or less disabling it:
如果您安装了模拟框架(例如 MockMVC),您可以创建 CommandLineRunner 实现的模拟实例,或多或少地禁用它:
@MockBean private TextProcessor myProcessor;
@MockBean 私有 TextProcessor myProcessor;
回答by Jan Petzold
Previous answers didn't work wor me. I ended up using different profiles - example for the init method in Spring Boot:
以前的答案对我不起作用。我最终使用了不同的配置文件 - Spring Boot 中的 init 方法示例:
SpringApplication app = new SpringApplication(AppConfig.class);
app.setAdditionalProfiles("production");
app.run(args);
This is not executed during the tests so we're safe here.
这不会在测试期间执行,所以我们在这里是安全的。
All tests have their own profile "test" (which is useful in many other ways, too):
所有测试都有自己的配置文件“测试”(这在许多其他方面也很有用):
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
public class MyFancyTest {}
The command-line runner is annotated with the "production" profile so the tests ignore it:
命令行运行器使用“生产”配置文件进行注释,因此测试将忽略它:
@Component
@Profile("production")
public class JobCommandLineRunner implements CommandLineRunner {}
回答by Dani
I solve this by not implementing CommandLineRunner. Just get a bean from the context, and call a method on it, passing argv. That way you will get the same result, and the application won't start automatically when running the tests.
我通过不实现 CommandLineRunner 来解决这个问题。只需从上下文中获取一个 bean,并在其上调用一个方法,传递 argv。这样,您将获得相同的结果,并且在运行测试时应用程序不会自动启动。