我正在构建一个spring boot应用程序。我想像这样运行它:
java -jar myjar.jar inputFile outputFile
如何为此编写@SpringBootTest
?我想使用@SpringBootTest
会使Spring在启动时失败,因为我的一些代码会说,"你需要提供一个inputFile和outputFile"。有没有办法在使用@SpringBootTest
时传递程序参数?
I'm inferring from this answer我可能必须使用SpringApplicationBuilder来执行此操作。
我思考我有答案,但我错了。这些不正确的信息可能对某些人有用:
(这个信息是错误的。我认为某些参数在代码中不能作为属性引用,但不是全部。我仍然不知道如何在一个参数中获取应用程序参数@SpringBootTest
)我很困惑,因为我不理解术语。注释具有"属性"的参数。我以为是将它指向属性文件but the documentation says:
表单中的属性key =应在测试运行之前添加到Spring Environment的值。
术语难题的另一部分是我所谓的"程序参数" Spring文档称为"属性"。
这是一种解决方法(不是答案)。你可以这样做:
private SpringApplicationBuilder subject;
@Before
public void setUp() throws Exception {
subject = new SpringApplicationBuilder(Application.class);
}
@Test
public void requiresInputAndOutput() throws Exception {
thrown.expect(IllegalStateException.class);
subject.run();
}
@Test
public void happyPathHasNoErrors() throws Exception {
subject.run(EXISTING_INPUT_FILE, "does_not_exist");
}
我不太喜欢这个。它阻止我在测试中的其他地方使用@Autowired
。
答案 0 :(得分:1)
我有同样的问题。 SpringBootContextLoader
(默认情况下与@SpringBootTest
一起使用)always runs your app without any arguments。但是,您可以提供自己的引导程序,然后引导程序可以提供您自己的SpringApplication
,该调用会被调用以运行测试。从那里,您可以覆盖run(String... args)
方法以提供所需的任何参数。
例如,给出一个简单的应用程序:
@SpringBootApplication
public class Main {
public static void main(final String[] args) {
new SpringApplicationBuilder(Main.class).run(args);
}
@Bean
public ApplicationRunner app() {
return args -> System.out.println(args.getOptionNames());
}
}
您可以使用以下命令注入测试参数:
@ContextConfiguration(classes = Main.class)
@ExtendWith(SpringExtension.class)
@BootstrapWith(RestartAppsTest.Bootstrapper.class)
class RestartAppsTest {
static class Bootstrapper extends SpringBootTestContextBootstrapper {
static class ArgumentSupplyingContextLoader extends SpringBootContextLoader {
@Override
protected SpringApplication getSpringApplication() {
return new SpringApplication() {
@Override
public ConfigurableApplicationContext run(String... args) {
return super.run("--restart");
}
};
}
}
@Override
protected Class<? extends ContextLoader> getDefaultContextLoaderClass(Class<?> testClass) {
return ArgumentSupplyingContextLoader.class;
}
}
@Test
void testRestart() {
//
}
}
它显然有点冗长,但可以。您可以清理它并制作一个更好/可重用的引导程序,以查找您自己的注释(或可能重用JUnit Jupiter的@Arguments
),该注释声明要提供的参数(而不是对其进行硬编码)。
答案 1 :(得分:0)
通常,您正在为您的服务编写测试;不是引导过滤器。 Spring Boot会将命令行参数传递给您的类 - 可能使用@Value注释,而@Value注释又是您服务的参数。考虑使用SpringRunner测试您的服务。这是我的代码库中的一个示例。
SELECT sum1, sum2
FROM (subquery1 here) as table1
JOIN (subquery2 here) as table2
ON (join condition);
答案 2 :(得分:0)
如果您应用的主要方法看起来有点不同,则可以使用@SpringBootTest(classes=Application.class, args ={inputFile, outputFile})
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
答案 3 :(得分:0)
对我来说工作示例是
@SpringBootTest(args ={"--env", "test"})
class QuickFixServerAppTest {
@Test
void loadContextTest() {
}
}
与传递相同
--env test
启动Spring时的参数