如果在TestCase类中有这样的注释:
@SpringApplicationConfiguration(classes = {Application.class})
这会导致实现Application.class
接口的CommandLineRunner
运行所需的方法
public void run(String... args) throws Exception
我仍然认为这主要是一种不想要的行为,因为在您的测试环境中,您可能不想启动整个应用程序。
我想到了解决这个问题的两个解决方案:
CommandLineRunner
类Application
界面
这个解决方案都需要大量编码。 你有更方便的解决方案吗?
答案 0 :(得分:38)
Jan的解决方案可以更容易实现。
在您的测试类中,激活“test”配置文件:
@Component
@Profile("!test")
public class JobCommandLineRunner implements CommandLineRunner {}
在CommandLineRunner中,将配置文件设置为NOT test:
My service method
@Transactional
public void saveUser() {
dao.saveUser();
}
My Dao method
public void saveUser() {
Session session = sessionFactory.withOptions().tenantIdentifier("master").openSession();
//Transaction transaction = session.beginTransaction();
//some dummy code to show case my problem
User user1 = new User();
user1.setUserName("manisha");
user1.setPassword("password");
user1.setFirstName("manisha first");
user1.setLastName("manisha last");
user1.setEmail("manisha@email.com");
user1.setState("Active");
user1.setTenantName("manisha");
session.persist(user1);
//transaction.commit();
session.close();
}
然后您不必在应用程序中手动设置配置文件。
答案 1 :(得分:20)
如春篇文档http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html中所述,您可以将 @ContextConfiguration 与特殊的初始值设定项一起使用:
ConfigFileApplicationContextInitializer 是一个 ApplicationContextInitializer ,可以应用于您的测试以加载Spring Boot application.properties 文件。当您不需要 @SpringApplicationConfiguration 提供的完整功能时,可以使用此功能。
在此示例中, anyComponent 已初始化并且已注入属性,但 run(args)方法将无法执行。 ( Application.class 是我的主要春季入口点)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class,
initializers = ConfigFileApplicationContextInitializer.class)
public class ExtractorTest {
@Autowired
AnyComponent anyComponent;
@Test
public void testAnyComponent() {
anyComponent.anyMethod(anyArgument);
}
}
答案 2 :(得分:17)
您可以在与应用程序相同的程序包中定义完全相同的测试配置,但不包括实现CommandLineRunner的bean。这里的关键是@ ComponentScan.excludeFilters:
@Configuration
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CommandLineRunner.class))
@EnableAutoConfiguration
public class TestApplicationConfiguration {
}
然后,只需替换测试中的配置:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestApplicationConfiguration.class)
public class SomeApplicationTest {
...
}
现在不会执行CommandLineRunner,因为它们不是配置的一部分。
答案 3 :(得分:12)
我参加派对有点晚了,但合理的方法是用@ConditionalOnProperty
来标记bean,例如
@ConditionalOnProperty(prefix = "job.autorun", name = "enabled", havingValue = "true", matchIfMissing = true)
public CommandLineRunner myRunner() {...}
以下注释将在测试中禁用它:
@SpringBootTest(properties = {"job.autorun.enabled=false"})
答案 4 :(得分:1)
以前的答案对我来说不起作用。我最终使用了不同的配置文件 - 例如Spring Boot中的init方法:
SpringApplication app = new SpringApplication(AppConfig.class);
app.setAdditionalProfiles("production");
app.run(args);
这在考试期间没有执行,所以我们在这里很安全。
所有测试都有自己的配置文件“test”(在许多其他方面也很有用):
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
public class MyFancyTest {}
命令行运行程序使用“生产”配置文件进行注释,因此测试会忽略它:
@Component
@Profile("production")
public class JobCommandLineRunner implements CommandLineRunner {}
答案 5 :(得分:1)
如果您安装了模拟框架(例如MockMVC),则可以创建CommandLineRunner实现的模拟实例,或多或少禁用它:
@MockBean 私有TextProcessor myProcessor;
答案 6 :(得分:0)
我通过不实现CommandLineRunner来解决这个问题。从上下文中获取一个bean,并在其上调用一个方法,传递argv。这样,您将获得相同的结果,并且应用程序在运行测试时不会自动启动。