簡體   English   中英

如何在@SpringBootTest 中傳遞程序參數?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM