【问题标题】:Layering or overriding ActiveProfiles within the Spring Framework在 Spring Framework 中分层或覆盖 ActiveProfile
【发布时间】:2014-09-04 21:22:20
【问题描述】:

有没有办法覆盖由 Spring 中的测试超类设置的 @ActiveProfile

这是我的配置:

<beans profile="integration">
    <bean class="org.easymock.EasyMock" factory-method="createMock">
        <constructor-arg value="com.mycompany.MyInterface" />
    </bean>
</beans>

<beans profile="production,one-off-test">
    <bean class="com.mycompany.MyInterfaceImpl" />
</beans>

所有测试的超类如下所示:

@ActiveProfiles("integration")
public abstract class TestBase {

在我的新测试课中,我想这样做:

@ActiveProfiles("one-off-test")
public class MyTest extends TestBase {

不从 TestBase 继承并不是一个真正的选择。 当我尝试运行它时,我得到的错误是:

No qualifying bean of type [com.mycompany.MyInterface] is defined: expected single matching bean but found 2
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.mycompany.MyInterface] is defined: expected single matching bean but found 2: org.easymock.EasyMock#1,com.mycompany.MyInterfaceImpl#0
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:970)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
    ... 46 more

更好的是能够对配置文件进行分层,以便如果存在配置文件one-off-test 的 bean,则注入该配置文件,否则注入 integration 配置文件 bean。

任何帮助将不胜感激。

【问题讨论】:

    标签: java spring integration-testing


    【解决方案1】:

    您可能需要通过系统属性指定活动配置文件:

    -Dspring.profiles.active="integration"
    

    如果您想使用相关的 bean 实现或

    -Dspring.profiles.active="one-off-test"
    

    使用 one-off-test 配置文件 bean。

    然后您必须将inheritProfiles 注释属性设置为false,这将防止当前带注释的测试用例丢弃子类配置文件:

    @ActiveProfiles(profiles = {"one-off-test"}, inheritProfiles= false)
    public class MyTest extends TestBase {}
    

    【讨论】:

    • 不错! +1! inheritProfiles 的存在让我忘记了
    • 是的,如果我在遇到类似情况时没有遇到它,我什至可以滑倒:D
    【解决方案2】:

    您提出的问题的一个解决方案是像这样使用primary

    <beans profile="integration">
        <bean class="org.easymock.EasyMock" factory-method="createMock" primary=true>
            <constructor-arg value="com.mycompany.MyInterface" />
        </bean>
    </beans>
    

    您不需要更改任何其他内容,因为 Spring 将使用来自配置文件 integration 的 bean,无论是 MyInterface 类型的 bean。尽管存在多个该类型的 bean,但 Spring 会这样做。

    查看this,其中提供了有关primary 工作原理的更多详细信息。

    【讨论】:

    • 美丽优雅的解决方案。谢谢!
    猜你喜欢
    • 2013-08-29
    • 1970-01-01
    • 2012-01-28
    • 2016-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    相关资源
    最近更新 更多