【发布时间】:2017-12-25 06:57:30
【问题描述】:
我有一个包含多个测试的 BaseTest 类。每个测试都应针对我列出的每个配置文件执行。
我考虑过使用参数化值,例如:
@RunWith(Parameterized.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
// @ActiveProfiles("h2-test") // <-- how to iterate over this?
public abstract class BaseTest {
@Autowired
private TestRepository test;
// to be used with Parameterized/Spring
private TestContextManager testContextManager;
public BaseTest(String profile) {
System.setProperty("spring.profiles.active", profile);
// TODO what now?
}
@Parameterized.Parameters
public static Collection<Object[]> data() {
Collection<Object[]> params = new ArrayList<>();
params.add(new Object[] {"h2-test" });
params.add(new Object[] {"mysql-test" });
return params;
}
@Before
public void setUp() throws Exception {
this.testContextManager = new TestContextManager(getClass());
this.testContextManager.prepareTestInstance(this);
// maybe I can spinup Spring here with my profile?
}
@Test
public void testRepository() {
Assert.assertTrue(test.exists("foo"))
}
我将如何告诉 Spring 使用这些不同的配置文件运行每个测试?事实上,每个配置文件都会与不同的数据源(内存中的 h2、外部 mysql、外部 oracle 等)通信,因此我的存储库/数据源必须重新初始化。
我知道我可以指定 @ActiveProfiles(...),甚至可以从 BaseTest 扩展并覆盖 ActiveProfile 注释。虽然这会起作用,但我只展示了我的测试套件的一部分。我的很多测试类都是从 BaseTest 扩展而来的,我不想为每个类创建几个不同的配置文件存根。目前工作,但丑陋的解决方案:
- BaseTest (@ActiveProfiles("mysql"))
- FooClassMySQL(来自 BaseTest 的注释)
- FooClassH2(@ActiveProfiles("h2"))
- BarClassMySQL(来自 BaseTest 的注释)
- BarClassH2(@ActiveProfiles("h2"))
- FooClassMySQL(来自 BaseTest 的注释)
谢谢
【问题讨论】:
-
为什么不使用参数运行所有测试,例如如果你使用 Maven,它可能是
mvn test -Dspring.profiles.active=test。我不确定你是否可以通过这个参数化类来实现它,主要是因为 Spring 很可能会在开始执行测试之前启动它的上下文,并且你必须在此之前设置活动配置文件。 -
谢谢。非常好的解决方案,我没有想过。如果在代码中没有一种优雅的方式来处理它,这肯定会做到!我认为唯一的问题可能是只有少数测试(事实上,我所有的存储库/jpa 测试)需要有不同的配置文件,而其他的不需要/需要访问不同的配置。
-
酷!如果它适合您,我会将其添加为答案。
-
这不是我目前正在寻找的答案,但如果没有优雅的代码相关解决方案,我肯定会将其标记为正确;)
-
近 2 年有代码相关的解决方案吗?
标签: java spring spring-boot junit parameterized