注释@ConditionalOnMissingBean在测试中不匹配

时间:2018-12-21 10:40:31

标签: java spring spring-boot

我有一个接口的两种实现-default和dev。我将@ConditionalOnProperty用于默认实现,并将@Profile@ConditionalOnMissingBean组合用于开发实现。

@Service
@ConditionalOnProperty(prefix = "keystore", value = "file")
public class DefaultKeyStoreService implements KeyStoreService {

@Service
@Profile("dev")
@ConditionalOnMissingBean(KeyStoreService.class)
public class DevKeyStoreService implements KeyStoreService {

现在,问题DevKeyStoreServiceTest正在测试DevKeyStoreService中。 我有这样的配置:

@SpringBootTest(
    classes = {DevKeyStoreService.class},
    properties = {"keystore.file="}
)
@RunWith(SpringRunner.class)
@ActiveProfiles("dev")
public class DevKeyStoreServiceTest {

    @Autowired
    private DevKeyStoreService tested;

    @Test
    public void testPrivateKey() {
    } //... etc.

结果是:

Negative matches:
-----------------
DevKeyStoreService:
   Did not match:
      - @ConditionalOnMissingBean (types: service.crypto.KeyStoreService; SearchStrategy: all) found bean 'devKeyStoreService' (OnBeanCondition)

和典型的org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'service.crypto.DevKeyStoreServiceTest'...

如何配置测试类以使其能够运行?

2 个答案:

答案 0 :(得分:1)

好,我知道了。

带有值@ConditionalOnMissingBean(KeyStoreService.class)的注释尝试仅查找具体实例,而接口KeyStoreService则没有。这样,它什么也找不到。

当我将注解与类型一起使用时,它就像一个魅力:@ConditionalOnMissingBean(type = "KeyStoreService")

答案 1 :(得分:0)

我认为最好的选择是使用@ConditionalOnMissingBean中的name选项。

您现在遇到的问题似乎是有条件的本身,而不是缺少的bean DefaultKeyStoreService。

如果您这样做

@ConditionalOnMissingBean(name="defaultKeyStoreService")

它可能会更好地工作。

另一种选择是专门创建一个产品概要文件来启用prod bean。

有趣的是,如果使用xml创建bean,则可以在拥有概要文件时覆盖bean。

所以,如果您有xml

<bean id="x" class="X"/>

然后有

<beans profile="dev">
  <bean id="x" class="Y"/>
</beans>

启用开发人员配置文件后,它将使用开发人员配置文件中的bean x替换未配置文件上下文中的x bean。

但是使用注释时不会发生相同的行为。

当个人资料出来时,我在这方面记录了一个bug,但并没有被占用。