我目前正在努力使用 Junit5,更准确地说是扩展和参数化测试。
我有以下测试目录结构:
.
└── daoimpl/
└── src/
├── main/
│ ├── java/
│ │ └── ...
│ └── resources/
│ └── ...
└── test/
├── java/
│ └── com/
│ └── foo/
│ └── baz/
│ ├── dao/
│ │ ├── ADaoTest.java
│ │ ├── Db1DaoTest.java
│ │ └── Db2DaoTest.java
│ └── resources/
│ ├── ATestResource.java
│ ├── Db1TestResource.java
│ └── Db2TestResource.java
└── resources/
└── ... // test context configurations
发出的类声明如下所示:
@ExtendWith(SpringExtension.class)
public abstract class ATestResource implements AfterEachCallback, BeforeEachCallback {
public List<String> schemas;
public Map<String, List<Table>> tables;
}
public final class Db1TestResource extends ATestResource {
@Override
public void afterEach(ExtensionContext context) {
// NOP
}
@Override
public void beforeEach(ExtensionContext context) {
initSchemas();
initTables();
}
}
@ExtendWith(SpringExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public abstract class ADaoTest {
@Autowired
DaoImpl dao;
abstract ATestResource getResource();
private Stream<Arguments> prepareSchemas() {
return getResource().schemas.stream()
.map(Arguments::of);
}
@ParameterizedTest
@MethodSource("prepareSchemas")
void getAllTablesForDefinedSchemasTest(String schema) {
final List<Table> extractedTables = dao.getAllTablesBySchema(schema);
assertTables(getResource().tables.get(schema), extractedTables);
}
// ...more tests
}
@ExtendWith(Db1TestResource.class)
@ContextConfiguration(locations = { "/Db1DaoTest.xml" })
class Db1DaoTest extends ADaoTest {
@RegisterExtension
Db1TestResource testResource = new Db1TestResource();
@Override
Db1TestResource getResource() {
return testResource;
}
}
基本上,我试图实现的是为不同类型的多个数据库提供一个测试套件。然后应将正确的延伸部分注入
ADaoTest
。如果我在单个测试场景中手动循环测试资源,一切都会正常。但是,这种解决方案并不透明,如果某些测试资源在回归时失败,则需要循环遍历所有模式和表,因此调试起来很不方便。
如果我尝试使用方法源中
Junit5getResource 的
ParametrizedTest
,则为null
。此外,它是在第一次测试运行之后null
(有时 - 不确定性行为)。
有谁知道如何解决这个问题,以便我可以使用参数化测试而不更改类结构?非常感谢任何帮助。
您遇到的问题是由于 Jupiter 的生命周期造成的:参数化测试的参数在调用 before-each 回调之前解析。 您的测试的零星“成功”源于
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
以及您通过
Db1TestResource
和 @ExtendWith
的双重注册 @RegisterExtension
。至少这是我明智的猜测。我看到的一个解决方案是,您不使用参数化测试,而是迭代测试本身中的表,例如
@Test
void getAllTablesForDefinedSchemasTest() {
getResource().schemas.forEach(schema -> {
final List<Table> extractedTables = dao.getAllTablesBySchema(schema);
assertTables(getResource().tables.get(schema), extractedTables);
});
}
或者,您可以使用
ParameterResolver
将表列表作为参数注入到测试方法中。
更新:另外,从@ExtendWith(Db1TestResource.class)
中删除
Db1DaoTest
。这不是必需的,因为您还使用了 @RegisterExtension
字段。