0

我正在尝试为我的项目实施基于 CSV 的测试。(因此在 test 文件夹中添加带有输入数据的 CSV 将导致 maven 启动新测试)。
现在我使用 SpringJUnitConfig 并使用 @Primary 覆盖项目设置。这是代码:(它会根据测试设置启动一个测试

package com.bch.score.test.framework;
@SpringJUnitConfig({FrameworkSpringContext.class})
public class MySingleTestLauncher {
    @Autowired
    public MainApplicationService service;
    @Autowired
    public TestDbService dbPreparationService;
    @Autowired
    public IFrameworkDatabaseConfig dbSettings;
    @Autowired
    public TestOutputChecker outputChecker;

    @Test
    public void testSingleCase() {
        dbPreparationService.fillDatabase(dbSettings);
        service.launchApp();
        outputChecker.checkResult();
    }
}

在我的 FrameworkSpringContext.class 中,我声明了应用程序包和测试包的组件扫描:

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@ComponentScan(value = {"com.bch.score.test.framework.config", "com.bch.score.cmd"})
public class FrameworkSpringContext {
    private final ISettingsProvider settings;

    @Autowired
    public FrameworkSpringContext(ISettingsProvider settings) {
        this.settings = settings;
    }

    @Bean
    public TestDbService service() {
        return new TestDbService();
    }

    @Bean
    public TestOutputChecker outputAssertion() {
        return new TestOutputChecker();
    }

    @Bean
    public IFrameworkDatabaseConfig dbSettings() {
        return new FrameworkDatabaseConfigImpl(settings.getUrl(), settings.getSchema(), settings.getLogin(), settings.getPassword());
    }
}

我还覆盖了在应用程序内部使用的设置 bean:

@PropertySource("classpath:score-framework.properties")
@Configuration
public class SettingsConfigurationFramework {
    @Primary
    @Bean(name = "testSettings")
    public ISettingsProvider settingsProvider(MessageSource messageSource, Environment environment) {
        return new SettingsProviderImpl(messageSource, environment);
    }
}

它运行良好,但使用这种方法,我需要为每个新测试复制 MySingleTestLauncher 和配置类。我想要的是使用@TestFactory,在每个文件夹的基础上创建测试。我想象测试启动器看起来像这样:

@SpringJUnitConfig({FrameworkSpringContext.class})
public class MultipleTestLauncher {
    @Autowired
    public TestDbService dbPreparationService;
    @Autowired
    public Function<String, IFrameworkDatabaseConfig> dbSettingsFactory;
    @Autowired
    public TestOutputChecker outputChecker;
    @TestFactory
    public Collection<DynamicTest> testTests() throws IOException {
        List<Path> subFolders = Files.list(Paths.get("src", "test", "resources", "framework", "tests"))
            .filter(path -> path.getFileName().toString().startsWith("test_"))
            .collect(Collectors.toList());
        List<DynamicTest> dynamicTests = new ArrayList<>();
        for (Path testPath : subFolders) {
        String currentTestFolder = testPath.getFileName().toString();
        dynamicTests.add(DynamicTest.dynamicTest(currentTestFolder, () -> {
            IFrameworkDatabaseConfig dbSettings = dbSettingsFactory.apply(currentTestFolder);
            dbPreparationService.fillDatabase(dbSettings);
            //TODO somehow create new Spring context for each app launch...
            //TODO getTestContext().getBean(MainApplicationService.class).launchApp();
            outputChecker.checkResult();
        }));
    }
    }
}

每个测试都像是一个新的应用程序启动。我希望将它们分开,以确保测试不会混淆彼此的输出。每个测试使用不同的 spring 上下文,我可以轻松地根据测试设置模拟 ISettingsProvider,并实现不同的断言。
所以我的问题是:为动态创建的测试初始化​​ spring 上下文的最佳实践是什么?
我应该查看上下文缓存(下面的链接)吗?
https://docs.spring.io/spring-framework/docs/4.2.0.RC2/spring-framework-reference/html/integration-testing.html#testcontext-ctx-management-caching
在我看来,创建新的应用程序上下文将是正确的做法,隔离每个测试应用程序启动,因此缓存可能不是这里的最佳选择。

4

1 回答 1

0

@DirtiesContext 可以帮助它指示关联的测试或类修改了 ApplicationContext。它告诉测试框架关闭并为以后的测试重新创建上下文。

于 2021-09-16T14:28:39.140 回答