[英]How do you pass program arguments in a @SpringBootTest?
我正在構建一個 spring boot 應用程序。 我想像這樣運行它:
java -jar myjar.jar inputFile outputFile
我如何為此編寫@SpringBootTest
? 我想象使用@SpringBootTest
會使 Spring 在啟動期間失敗,因為我的一些代碼會說,“你需要提供一個 inputFile 和 outputFile”。 使用@SpringBootTest
時有沒有辦法傳遞程序參數?
我從這個答案推斷我可能必須使用 SpringApplicationBuilder 來執行此操作。
我以為我有答案,但我錯了。 這個不正確的信息可能對某些人仍然有用:
(這個信息是錯誤的。我認為有些參數不能在代碼中作為屬性引用,但不是全部。我仍然不知道如何在@SpringBootTest
中獲取應用程序參數)我很困惑,因為我沒有不懂術語。 注釋有一個“屬性”參數。 我以為是將它指向一個屬性文件,但文檔說:
在測試運行之前應該添加到 Spring 環境中的 key=value 形式的屬性。
另一個術語難題是我稱之為“程序參數”的東西,Spring 文檔將其稱為“屬性”。
這是一些額外的相關文檔: https ://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-application-arguments
這是一種解決方法(不是答案)。 你可以這樣做:
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
。
如果你的程序參數是
--arg1=val1
在 springboot 版本 2.2.0 之前你可以使用
@SpringBootTest({"arg1=val1"})
在 springboot 2.2.0 之后你可以使用
@SpringBootTest(args={"--arg1=val1"})
我遇到過同樣的問題。 開箱即用的SpringBootContextLoader
(默認情況下與@SpringBootTest
一起使用) 始終在不帶任何參數的情況下運行您的應用程序。 但是,您可以提供自己的引導程序,然后它又可以提供您自己的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
)聲明要提供的參數(而不是對它們進行硬編碼)。
如果您的應用程序的主要方法看起來有點不同,您可以使用@SpringBootTest(classes=Application.class, args ={inputFile, outputFile})
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
對我來說工作的例子是
@SpringBootTest(args ={"--env", "test"})
class QuickFixServerAppTest {
@Test
void loadContextTest() {
}
}
與通過相同
--env test
啟動Spring時的爭論
通常,您正在為您的服務編寫測試; 不是引導帶。 Spring Boot 會將命令行參數傳遞給您的類 - 可能使用 @Value 注釋,這又將成為您服務的參數。 考慮使用 SpringRunner 測試您的服務。 這是我的代碼庫中的一個示例。
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {
Neo4jConfigTest.class,
FdTemplate.class,
FdServerIo.class,
MapBasedStorageProxy.class})
@ActiveProfiles({"dev", "fd-auth-test", "fd-client"})
public class TestEntityLinks {
@Autowired
private ContentModelService contentModelService;
@Autowired
private BatchService batchService;
@Test
public void doSomething () { ... }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.