2013-02-04 17 views
5

mam ten fasoli w moim config Wiosna Java:Jak zastąpić komponent o określonym zakresie w celu przeprowadzenia testów?

@Bean 
@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, value=SpringScopes.DESKTOP) 
public BirtSession birtSession() { 
    return new BirtSession(); 
} 

Dla testów, muszę makiety bez zakresie (nie ma „Pulpit” zakres w teście). Ale kiedy utworzyć konfigurację dla mojego testu, który importuje powyższą konfigurację i zawiera:

@Bean 
public BirtSession birtSession() { 
    return new MockSession(); 
} 

dostaję „Desktop” scoped szydzili fasoli :-(

Jak zrobić Wiosna „zapomnieć” THE @Scope ? adnotacja

. PS: To działa, gdy nie używam @Import i używać skopiować & pastę ale nie chcę tego robić

+0

Jaki rodzaj testu piszesz? Test jednostkowy? –

+1

Co powiesz na opisywanie 'birtSession()' z '@ Primary'? * Niektóre * zakres 'DESKTOP' muszą być dostępne, ale funkcja automatycznego uzbrojenia zawsze wybierze główny komponent. –

+0

@JBNizet: Tak, to jest test JUnit, który używa 'SpringJUnit4ClassRunner' –

Odpowiedz

1

Problem wydaje się być ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod() który wykorzystuje ScopedProxyCreator.createScopedProxy() metody statycznej, aby stworzyć scoped definicji Bean

// replace the original bean definition with the target one, if necessary 
     BeanDefinition beanDefToRegister = beanDef; 
     if (proxyMode != ScopedProxyMode.NO) { 
      BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
        new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS); 
      beanDefToRegister = proxyDef.getBeanDefinition(); 
    } 

Jako BeanDefinitionHolder Zwraca RootBeanDefinition zamiast ConfiguratioClassBeanDenition definicja zawężona fasoli proxy (tj ScopedProxyFactoryBean) nie może zostać przesłonięte przez inną klasę konfiguracji Java.

Rozwiązaniem mogłoby być deklarowania scoped fasolę, aby zastąpić w pliku konfiguracyjnym XML i importowanie go z @ImportResource.

+0

To brzmi jak błąd/funkcja. Czy jest to zamierzone, czy też powinienem zgłosić to jako błąd? –

+0

Myślę, że to błąd. ConfigurationClassBeanDefinitionReader nie powinien rejestrować RootBeanDefinitions, ponieważ ma własną klasę BeanDefinition, aby określić, czy definicja komponentu bean została utworzona zewnętrznie. –

+0

Uważam, że powinieneś zgłosić ten błąd, ponieważ wydaje się, że wiesz, o czym mówisz :-) Dodaj adres URL do odpowiedzi lub jako komentarz po tym. –

0

problemem nie jest wiosna utrzymywania adnotacji The Probl em jest taka, że ​​Spring najpierw próbuje przeanalizować "produktywną" konfigurację i aby to zrobić, sprawdza, czy zakres jest dostępny. Wiosna sprawdza skrzętnie zakresy. Dlatego nigdy nie przechodzi do drugiej/nadrzędnej definicji fasoli.

utworzyć obszar atrapę:

import java.util.HashMap; 
import java.util.Map; 
import org.springframework.beans.factory.ObjectFactory; 

public class MockSpringScope implements org.springframework.beans.factory.config.Scope { 

    private Map<String, Object> objects = new HashMap<String, Object>(); 

    @Override 
    public Object get(String name, ObjectFactory<?> objectFactory) { 
     Object result = objects.get(name); 
     if(null == result) { 
      result = objectFactory.getObject(); 
      objects.put(name, result); 
     } 
     return result; 
    } 

    @Override 
    public Object remove(String name) { 
     return objects.remove(name); 
    } 

    @Override 
    public void registerDestructionCallback(String name, Runnable callback) { 
     // NOP 
    } 

    @Override 
    public Object resolveContextualObject(String key) { 
     // NOP 
     return null; 
    } 

    @Override 
    public String getConversationId() { 
     // NOP 
     return null; 
    } 

} 

i zarejestrować jako że pod "pulpitu" zakresu. To pozwoli Springowi na pomyślne przeanalizowanie konfiguracji produkcyjnej.