@ActiveProfiles在元注释和测试类上无效

7
我创建了一个元注释 @EmbeddedMongoDBUnitTest,用于激活两个配置文件在基于Spring的单元测试中使用。基本设置已经生效:
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ActiveProfiles({"embeddedMongoDB", "embeddedMongoDBUnitTest"})
public @interface EmbeddedMongoDBUnitTest {
}

@RunWith(SpringJUnit4ClassRunner.class)
@EmbeddedMongoDBUnitTest
@ContextConfiguration(...)
public class WorkingTest {
    ...
}

现在,当尝试在测试类本身上使用另一个@ActiveProfiles注释来激活另一个配置文件时,@EmbeddedMongoDBUnitTest中的配置文件将不再被激活:

@RunWith(SpringJUnit4ClassRunner.class)
@EmbeddedMongoDBUnitTest
@ActiveProfiles({"h2IntegrationTests"})
@ContextConfiguration(...)
public class NotWorkingTest {
    ...
}

这个问题出在哪里?是Spring测试代码的bug还是其他原因导致的?

1个回答

12

这不是一个错误:这是由设计所决定的。

这种形式的配置在Spring中根本不被支持,因此无法起作用。

当Spring Framework搜索注释时使用的算法会在找到第一个符合条件的注释后停止搜索。因此,在你的示例中,NotWorkingTest上的@ActiveProfiles注释有效地覆盖了你组合的@EmbeddedMongoDBUnitTest注释上的@ActiveProfiles注释。

请注意,这是核心Spring Framework注释的一般语义。换句话说,您遇到的行为不特定于spring-test模块。

话虽如此,通过@ActiveProfiles声明的配置文件实际上会在测试类继承结构中得到继承(除非将inheritProfiles标志设置为false)。但不要混淆类继承结构和注释继承结构:Java支持接口和类的继承,但不支持注释的继承。

希望这能澄清问题!

Sam(spring-test模块的组件负责人)


感谢你的探索,Sam。如果这不是一个错误,我对这里的设计表示质疑。虽然Spring框架只搜索第一个注释可能是正确的,但在这种情况下,人们真的期望所有@ActiveProfiles注释都被捕获,特别是如果它支持类继承。 - James
James,欢迎在http://jira.spring.io上创建一个JIRA问题来请求这样的功能,我们会考虑它。 - Sam Brannen
从Spring 4开始,@ActiveProfiles已经变成了一个元注释,现在可能是说这是个好时机。 - usr-local-ΕΨΗΕΛΩΝ
@ActiveProfiles 本身并不是元注解。自 Spring 4 版本以来,它可以用作元注解。然而,OP 显然已经在使用 Spring 4+,因为他的 @EmbeddedMongoDBUnitTest 可以独立工作。 - Sam Brannen
可组合的@ActiveProfiles问题请参考https://github.com/spring-projects/spring-framework/issues/26145 - drekbour
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接