首页 文章

为什么Spring @Qualifier不适用于Spock和Spring Boot

提问于
浏览
0

我正在尝试为Spock中的控制器编写测试 .

@ContextConfiguration(loader = SpringApplicationContextLoader.class,
    classes = [Application.class, CreateUserControllerTest.class])
@WebAppConfiguration
@Configuration
class CreateUserControllerTest extends Specification {

    @Autowired
    @Qualifier("ble")
    PasswordEncryptor passwordEncryptor

    @Autowired
    UserRepository userRepository

    @Autowired
    WebApplicationContext context

    @Autowired
    CreateUserController testedInstance

    def "Injection works"() {
        expect:
        testedInstance instanceof CreateUserController
        userRepository != null
    }

    @Bean
    public UserRepository userRepository() {
        return Mock(UserRepository.class)
    }

    @Bean(name = "ble")
    PasswordEncryptor passwordEncryptor() {
        return Mock(PasswordEncryptor)
    }

}

应用程序类只是Spring Boot最简单的配置(启用自动扫描) . 它提供了一个带PasswordEncryptor . 我想用我的bean替换这个bean来提供一个模拟 .

但不幸的是Spring抛出NoUniqueBeanDefinitionException:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.jasypt.util.password.PasswordEncryptor] is defined: expected single matching bean but found 2: provide,ble
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 54 more

@Qualifier注释似乎根本不起作用 . 我能做什么?

Edit

问题不在 CreateUserControllerTest 中,而在 CreateUserController 中 .

public class CreateUserController {
    @Autowired
    private PasswordEncryptor encryptor;
}

没有 @Qualifier 注释,因此Spring不知道如何使Spring通过本地配置从Application替换 PasswordEncryptor bean .

1 回答

  • 1

    @Qualifier 用于连接bean的特定实例,如果您有多个相同接口的实现 .

    但是你仍然需要在spring上下文中为每个bean提供一个'UNIQUE'名称 .

    所以你试图注册两个名为' passwordEncryptor '. One in your test, and it seems the other one is in your actual code ' Application.class '的bean .

    如果要模拟'PasswordEncryptor',请使用 @Mock@Spy . (或)如果要避免错误,请更改方法的名称以避免实例名称冲突 .

    @Mock
    private PasswordEncryptor passwordEncryptor;
    
    or
    
    @Spy
    private PasswordEncryptor passwordEncryptor;
    

    Edit

    该错误的另一种可能性是在代码中为某个地方定义 @Autowired 为' passwordEncryptor '而没有 @Qualifier 标记,

    你有两个 @Bean(name="...") passwordEncryptor 定义的实例,所以Spring上下文很困惑,选择哪一个'Auto Wire'字段 .

相关问题