测试使用其他测试的内部ContextConfiguration

3
我在项目中创建了一个新的测试。对于这个测试,我使用了与测试类相同的内部配置类中的@ContextConfiguration。但是现在我的其他测试失败了,因为它们正在使用新测试的配置。

这怎么可能呢?我曾经认为不可能从外部使用测试类内部的配置。

当我从新测试中移除内部配置时,所有其他测试都能正常运行。

@DataJpaTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ContextConfiguration(classes = EventServiceTest.Config.class)
class EventServiceTest {
    @Configuration
    @Import({WorkingTimeConfig.class,
             PartnerConfig.class,
             ProjectConfig.class,
             UserConfig.class,
             AccountGroupConfig.class,
             LanguageConfig.class,
             CountryConfig.class,
             EventConfig.class,
             LanguageConfig.class})
    static class Config {
        @SuppressWarnings("unused")
        @MockBean(reset = MockReset.BEFORE)
        private UserAttendanceBoard userAttendanceBoard;

        @Bean
        public PasswordEncoder passwordEncoder() {
            return PasswordEncoderFactories.createDelegatingPasswordEncoder();
        }

        @Bean
        public ImpersonateProperties impersonateProperties() {
            return new ImpersonateProperties();
        }
    }
...
}

现在这个测试无法运行:

最初的回答:

@Import(MailSenderAutoConfiguration.class)
@DataJpaTest
@Transactional
public class ServiceTimeEntryServiceTest {

    private ServiceTimeService serviceTimeService;
    private ServiceTimeEntryRepository repository;

    @Autowired
    public ServiceTimeEntryServiceTest(ServiceTimeService serviceTimeService, ServiceTimeEntryRepository repository) {
        this.serviceTimeService = serviceTimeService;
        this.repository = repository;
    }

    @Test
    void getAllByAccountId() {...}

如果我尝试启动我的旧测试,就会出现此错误:

org.springframework.beans.factory.support.BeanDefinitionOverrideException: 在类路径资源[de/hlservices/timetracking/api/business/event/EventServiceTest$Config.class]中定义的名称为“passwordEncoder”的无效bean定义:无法注册bean定义

谢谢您的帮助 :)

"Original Answer"翻译成"最初的回答"

2个回答

1
正如Maciej Kowalski所指出的那样,这个问题可能与@ ComponentScan注释有关。
如果您正在使用它,请考虑添加一个excludeFilter以确保您只获得真正想要的内容。您可能希望排除其他配置类被您的@ComponentScan注释找到:
@ComponentScan(excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,
                value = Configuration.class)
})

顺便说一句:我非常推荐使用IntelliJ IDEA作为IDE,因为它有很棒的Spring支持。你只需要点击代码左侧的绿色图标(第9行),就可以查看扫描到的bean/component。

IntelliJ IDEA Spring Support

这使得调试扫描问题变得更加容易。

就是这样!非常感谢您 :) 我现在已经在所有的配置中添加了过滤器。 - undefined

0

在我的项目中,我遇到了同样的问题,原因是@ComponentScan也会因为@Configuration注解而扫描到那个类。

当我移除了那个注解后,一切都正常工作了,这样组件扫描就会忽略它。所以你可以这样做:

@Import({WorkingTimeConfig.class,
             PartnerConfig.class,
             ProjectConfig.class,
             UserConfig.class,
             AccountGroupConfig.class,
             LanguageConfig.class,
             CountryConfig.class,
             EventConfig.class,
             LanguageConfig.class})
    static class Config {

移除 @Configuration 注解并不能阻止 @ContextConfiguration(classes = EventServiceTest.Config.class) 配置仍然将其引入。


移除@Configuration注解也会移除对该类的特殊处理,使其不再被视为配置类。将其添加到@Import中并不能使其成为一个真正意义上的配置类,而是一种轻量级的配置模式(一个带有@Bean方法的普通组件)。这些被区别对待的方式可能会导致令人惊讶的效果! - undefined
1
哇,我不知道这一点。谢谢你指出来。确实,我的内部测试配置类中没有任何额外的注释。也许这就是为什么我没有看到任何问题的原因。 - undefined
谢谢你的回答。你是对的,当我移除@Configuration注解后,所有其他的测试都能再次正常工作。但是现在新的测试不起作用,因为它没有使用内部的配置类。 java.lang.IllegalStateException: 无法检索@EnableAutoConfiguration基础包 - undefined

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