【问题标题】:Problems autowiring beans to TestNG test when using spring profiles使用弹簧配置文件时自动装配 bean 到 TestNG 测试的问题
【发布时间】:2023-04-06 01:30:01
【问题描述】:

我目前正在完善我们拥有的测试框架。对于当前的需求,我们必须支持多个弹簧配置文件,并多次运行我们的测试,每次使用不同的配置文件。每个配置文件都针对不同的测试环境,因此可以执行具有不同逻辑的不同测试集。

我有一个这样的测试课:

@ContextConfiguration(locations = { "classpath:META-INF/test-context.xml" })
public class Test extends AbstractTestNGSpringContextTests {
    @Autowired
    ProfileSpeciticBean profileSpecificBean;

    ...
}

这里,ProfileSpecificBean 是一个接口,由不同的类实现。要注入的实际实现由活动的 Spring 配置文件决定,我使用的是 Spring XML 上下文。我正在使用 Maven 构建项目,使用 -Dspring.profiles.active=profileName 命令,因此期望测试能够捕获通过的配置文件。

但是,当前测试在完整堆栈跟踪中失败并出现此错误:

org.springframework.beans.factory.NoSuchBeanDefinitionException: 没有为依赖找到 ProfileSpeciticBean 类型的合格 bean: 预计至少有 1 个符合自动装配候选资格的 bean,找到 0

在对该主题进行一些研究后,我发现 AbstractTestNGSpringContextTests 需要在测试类顶部添加 @ActiveProfiles 注释。所以,这段代码有效:

 @ContextConfiguration(locations = { "classpath:META-INF/test-context.xml" })
 @ActiveProfiles("profile1")
 public class Test extends AbstractTestNGSpringContextTests ...

这样做的问题是:我想避免在我的类中硬编码配置文件名称。我需要为不同的配置文件运行相同的测试类,只需更改命令行脚本。

以上可能吗?有没有办法让 TestNG 知道命令行配置文件,并重新使用相同的测试?我需要避免重复代码和配置以使我的测试运行,因此为每个配置文件创建两个测试类不是我想要的。

【问题讨论】:

    标签: java spring testng spring-profiles


    【解决方案1】:

    尝试关注How to set JVM parameters for Junit Unit Tests? 为实际运行测试的虚拟机设置系统变量 - 它与运行 maven 的虚拟机不同。

    在那里设置您的个人资料。

    您可以使用 maven 系统参数通过调用 maven(或使用 maven 配置文件)进行设置。

    【讨论】:

    • 感谢@Michael,您的链接将我引向了解决方案。特别是,我必须更改我的surefire 插件配置以将这一行:<argLine>-Dspring.profiles.active=${spring.profiles.active}</argLine> 包含在configuration 部分中,正如this answer 为您链接的线程所指出的那样。在我的设置中,${spring.profiles.active} 是我的 maven 构建配置文件定义的属性,表示与其关联的 spring 配置文件。
    • 如果我当时知道怎么做,我会链接答案 - 现在我知道怎么做:-P
    【解决方案2】:

    为了获得更准确的答案,我建议您添加堆栈跟踪和您的主要配置部分(您声明的 bean 应该被测试 bean 替换)。

    大致思路如下:

    假设您想根据您的个人资料更改 PropertyPlaceholderConfigurer。

    步骤:

    1. 你创建你的 main-config.xml 包含 PropertyPlaceholderConfigurer 并用 profile="default" 标记它
    2. 您使用 PropertyPlaceholderConfigurer 的测试实现创建 test-config.xml
      (不要忘记将 test-config.xml 标记为 profile="MyTestProfile" 或仅将 PropertyPlaceholderConfigurer 标记为 profile="MyTestProfile)
    3. 然后将 test-config.xml 和 main-config.xml 都导入到测试中

     

     @ContextConfiguration(locations = { "classpath:META-INF/main-config.xml","classpath:META-INF/test-config.xml" })
     @ActiveProfiles("MyTestProfile")
     public class Test extends AbstractTestNGSpringContextTests {}
    

    它应该工作。祝你好运。

    【讨论】:

    • 感谢您的回答。实际上,我想删除 @ActiveProfiles("MyTestProfile") 部分。我希望能够使用profile1profile2 运行相同的Test 类,具体取决于命令行。因此,我必须避免在课堂上硬编码配置文件名称。我已经使用 @ActiveProfiles 注释完成了这项工作
    猜你喜欢
    • 1970-01-01
    • 2012-11-02
    • 2011-11-27
    • 2021-12-12
    • 1970-01-01
    • 2016-12-13
    • 2012-10-18
    • 2020-09-09
    • 1970-01-01
    相关资源
    最近更新 更多