2015-04-28 110 views
0

我想爲Spock中的控制器編寫一個測試。爲什麼Spring @Qualifier不能與Spock和Spring Boot配合使用

@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) 
    } 

} 

應用類只是春天啓動簡單的配置(使自動掃描)。它提供了一個與PasswordEncryptor。我想用Application提供一個模擬來替換這個bean。

但不幸的是春天拋出一個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通過本地配置來取代Application中的PasswordEncryptor bean。

+0

我強烈建議使用構造函數注入。這使您可以輕鬆控制注入到受測試的類中的內容。 – chrylis

回答

1

@Qualifier用於連接特定的bean實例,如果您有多個相同接口的實現。

但仍然需要在每個bean的春天上下文中使用'UNIQUE'名稱。

所以你試圖註冊名爲'passwordEncryptor'的兩個豆。一個在你的測試中,而另一個在你的實際代碼'Application.class'中。

如果您想模擬'PasswordEncryptor',請使用@Mock@Spy。 (或)如果要避免該錯誤,請更改該方法的名稱以避免實例名稱衝突。

@Mock 
private PasswordEncryptor passwordEncryptor; 

or 

@Spy 
private PasswordEncryptor passwordEncryptor; 

編輯

是錯誤的另一種可能是你沒有@Qualifier標籤定義爲 'passwordEncryptor' 的@Autowired你的代碼的某個地方,

你有定義了@Bean(name="...") passwordEncryptor的兩個實例,所以Spring上下文與選擇混淆t哪一個「自動佈線」場。

+0

除非我遺漏了預期的單個匹配bean,但發現2:provide,ble'意味着這些bean具有不同的名稱。 – Morfic

+0

感謝morfic。編輯答案。 – K139

+0

謝謝你們。現在我發現在測試中沒有自動裝配字段的問題,但在測試的實例中。 'CreateUserController'在內部具有'@ Autowired'註釋到'passwordEncryptor'但沒有限定符,所以存在衝突。不幸的是,我不能使用'@ Mock'註釋,因爲我想使用Spock的模擬框架(它不提供模擬注入)。 – milus

相關問題