为什么 Spring @Qualifier 不适用于 Spock 和 Spring Boot
Why Spring @Qualifier does not work with Spock and Spring Boot
我正在尝试为 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)
}
}
应用程序 class 只是 Spring 引导最简单的配置(启用自动扫描)。它提供了一个密码加密器。我想用我提供模拟的 bean 替换 Application 中的这个 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 注释似乎根本不起作用。我能做什么?
编辑
问题不在 CreateUserControllerTest
而在 CreateUserController
。
public class CreateUserController {
@Autowired
private PasswordEncryptor encryptor;
}
没有 @Qualifier
注解,所以 Spring 不知道应该注入哪个 bean。不幸的是,我不知道如何使 Spring 通过本地配置从应用程序中替换 PasswordEncryptor
bean。
@Qualifier
是连接特定的 bean 实例,如果您有同一接口的多个实现。
但在 spring 上下文中,您仍然需要为每个 bean 取一个 'UNIQUE' 名称。
所以您正在尝试注册两个名称为“passwordEncryptor
”的 bean。一个在你的测试中,另一个似乎在你的实际代码中'Application.class
'。
如果您想模拟 'PasswordEncryptor',请使用 @Mock
或 @Spy
。 (or) 如果你想避免错误,那么改变方法的名称以避免实例名称冲突。
@Mock
private PasswordEncryptor passwordEncryptor;
or
@Spy
private PasswordEncryptor passwordEncryptor;
编辑
该错误的另一种可能性是您在代码中的某处为“passwordEncryptor
”定义了 @Autowired
而没有 @Qualifier
标记,
但是
您定义了两个 @Bean(name="...") passwordEncryptor
实例,因此 Spring 上下文与 select 混淆,哪个 'Auto Wire' 字段。
我正在尝试为 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)
}
}
应用程序 class 只是 Spring 引导最简单的配置(启用自动扫描)。它提供了一个密码加密器。我想用我提供模拟的 bean 替换 Application 中的这个 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 注释似乎根本不起作用。我能做什么?
编辑
问题不在 CreateUserControllerTest
而在 CreateUserController
。
public class CreateUserController {
@Autowired
private PasswordEncryptor encryptor;
}
没有 @Qualifier
注解,所以 Spring 不知道应该注入哪个 bean。不幸的是,我不知道如何使 Spring 通过本地配置从应用程序中替换 PasswordEncryptor
bean。
@Qualifier
是连接特定的 bean 实例,如果您有同一接口的多个实现。
但在 spring 上下文中,您仍然需要为每个 bean 取一个 'UNIQUE' 名称。
所以您正在尝试注册两个名称为“passwordEncryptor
”的 bean。一个在你的测试中,另一个似乎在你的实际代码中'Application.class
'。
如果您想模拟 'PasswordEncryptor',请使用 @Mock
或 @Spy
。 (or) 如果你想避免错误,那么改变方法的名称以避免实例名称冲突。
@Mock
private PasswordEncryptor passwordEncryptor;
or
@Spy
private PasswordEncryptor passwordEncryptor;
编辑
该错误的另一种可能性是您在代码中的某处为“passwordEncryptor
”定义了 @Autowired
而没有 @Qualifier
标记,
但是
您定义了两个 @Bean(name="...") passwordEncryptor
实例,因此 Spring 上下文与 select 混淆,哪个 'Auto Wire' 字段。