Junit5:测试扩展的注入在多个测试中为空

问题描述 投票:0回答:1

我目前正在努力使用 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

发出的类声明如下所示:

ATestResource.java

@ExtendWith(SpringExtension.class)
public abstract class ATestResource implements AfterEachCallback, BeforeEachCallback {

    public List<String> schemas;

    public Map<String, List<Table>> tables;
}

Db1TestResource.java

public final class Db1TestResource extends ATestResource {

    @Override
    public void afterEach(ExtensionContext context) {
        // NOP
    }

    @Override
    public void beforeEach(ExtensionContext context) {
        initSchemas();
        initTables();
    }
}

ADaoTest.java

@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
}

Db1DaoTest.java

@ExtendWith(Db1TestResource.class)
@ContextConfiguration(locations = { "/Db1DaoTest.xml" })
class Db1DaoTest extends ADaoTest {

    @RegisterExtension
    Db1TestResource testResource = new Db1TestResource();

    @Override
    Db1TestResource getResource() {
        return testResource;
    }
}

基本上,我试图实现的是为不同类型的多个数据库提供一个测试套件。然后应将正确的延伸部分注入

ADaoTest
。如果我在单个测试场景中手动循环测试资源,一切都会正常。但是,这种解决方案并不透明,如果某些测试资源在回归时失败,则需要循环遍历所有模式和表,因此调试起来很不方便。

如果我尝试使用方法源中

Junit5
getResource 的ParametrizedTest,则为
null
。此外,它是在第一次测试运行之后
null
(有时 - 不确定性行为)。

有谁知道如何解决这个问题,以便我可以使用参数化测试而不更改类结构?非常感谢任何帮助。

java junit junit5 spring-test junit-jupiter
1个回答
0
投票

您遇到的问题是由于 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
字段。
    

© www.soinside.com 2019 - 2024. All rights reserved.