如何将 Spring bean 注入 JUnit Jupiter ExecutionCondition

How to inject Spring beans into a JUnit Jupiter ExecutionCondition

提问人:Fimoknat 提问时间:11/12/2023 最后编辑:Sam BrannenFimoknat 更新时间:11/12/2023 访问量:180

问:

我有自定义接口“平台”,带有@ExtendWith注释和实现 ExecutionCondition 的类。

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@ExtendWith(PlatformExecutionCondition.class)
public @interface Platform {

    MobilePlatform[] value();

@Component
@RequiredArgsConstructor
public class PlatformExecutionCondition implements ExecutionCondition {

    private final EmulatorConfigProperties emulatorConfigProperties;

    private final PlatformAnnotationManager platformAnnotationManager;

    @Override
    public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext   extensionContext) {
        MobilePlatform platform =       MobilePlatform.getByName(emulatorConfigProperties.getPlatformName());
        if (platform == null) {
            return disabled("Mobile platform is not specified");
        }
        if (extensionContext.getTestMethod().isEmpty()) {
            return enabled("Test class execution enabled");
        }

        Set<MobilePlatform> mobilePlatforms = platformAnnotationManager.getTestMobilePlatforms(extensionContext);
        if (mobilePlatforms.contains(platform)) {
            return enabled(format("{0} mobile platform is available for testing", platform.getName()));
        } else {
            return disabled(format("{0} mobile platform is not available for testing",   platform.getName()));
        }
    }
 }

运行测试时,我发现一个错误 java.lang.NoSuchMethodException: com.mob.market3b.platform.execution.PlatformExecutionCondition.<init>() 如果我删除注释,则测试将运行而不会出错,但随后未使用 evaluateExecutionCondition 方法。如何在 Spring 中使用@ExtendWith注解?

Java Spring junit5 spring-annotations

评论

1赞 Slaw 11/12/2023
JUnit 5 要求扩展在注册时具有无参数构造函数。有关详细信息,请参阅扩展。类的 @RequiredArgsConstructor 注释意味着您没有无参数构造函数。您是否在问如何将依赖项注入 JUnit 扩展?@ExtendWith
0赞 Fimoknat 11/12/2023
是的!我尝试使用 AllArgsConstructor 和 NoArgsConstructor 代替 RequiredArgsConstructor - 然后我有这样的错误:无法评估条件 [com.mob.market3b.platform.execution.PlatformExecutionCondition]:无法调用“com.mob.market3b.config.EmulatorConfigProperties.getPlatformName()”,因为“this.emulatorConfigProperties”为空。我能@Slaw做什么?

答:

3赞 Sam Brannen 11/12/2023 #1

如前所述,@slaw必须有一个默认的 no-args 构造函数。PlatformExecutionCondition

因此,中的字段不能是 。PlatformExecutionConditionfinal

尽管您可以在 your 中创建 as a bean 的实例,并将其注入到 test 类中注释 and 的字段中(参见 https://stackoverflow.com/a/50251190/388980),但从自定义 JUnit Jupiter 扩展中访问 Bean 的最简单方法是从 -- 例如通过 .PlatformExecutionConditionApplicationContext@Autowired@RegisterExtensionApplicationContextApplicationContextgetBean(<bean type>)

您可以在 via 中访问应用程序上下文。PlatformExecutionConditionorg.springframework.test.context.junit.jupiter.SpringExtension.getApplicationContext(ExtensionContext)

Смотритетакже: https://stackoverflow.com/a/56922657/388980

警告

请注意,通常不建议在实现中访问 (或应用程序上下文中的 bean),因为这样您就可以有效地强制创建一个否则不会使用的 (如果最终禁用了测试)。有关详细信息,请参阅 @DisabledIf(loadContext) 的文档。ApplicationContextExecutionConditionExecutionConditionApplicationContextExecutionCondition

旁注

Spring 和 annotations 可能是实现自己的 .@EnabledIf@DisabledIfExecutionCondition