2017-12-13 3 views
-1

Ich habe einen @Service Bean, die ich static Zugang zu müssen:Wie verspottet man statischen Zugriff auf federgeführte @Bean mit Mockito?

@Service 
public class MyBean implements InitializingBean { 
    private static MyBean instance; 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     instance = this; 
    } 

    public static MyBean get() { 
     return instance; 
    } 

    public String someMethod(String param) { 
     return "some"; 
    } 
} 

Verbrauch:

@Service 
public class OtherService { 
    public static void makeUse() { 
     MyBean myBean = MyBean.get(); 
    } 
} 

Problem: wenn ich eine Integration junit Test für OtherService schreiben, die Verwendung des Stat MyBean Zugangs macht, Die instance Variable ist immer Null.

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class ITest { 
    @Autowired 
    private OtherService service; 

    @MockBean 
    private MyBean myBean; 

    @Before 
    public void mock() { 
     Mockito.when(myBean.someMethod(any()).thenReturn("testvalue"); 
    } 

    @Test 
    public void test() { 
     service.makeUse(); //NullPointerException, as instance is null in MyBean 
    } 
} 

Frage: wie kann ich einen Integrationstest schreiben, wenn diese Art von statischem Zugriff auf eine feder Managed Bean mit?

+6

Meine erste Frage ist, warum Sie die Bohne über ein statisches Feld zugreifen kann wenn der Benutzer der Bohne auch federgeführt wird? Sie können die Singelton-Instanz durch Feder injizieren –

+0

Dies ist nur ein Beispiel. In meinem Code ist die Hierarchie viel tiefer und irgendwann muss ich in einer statischen Klasse auf diesen Dienst zugreifen. Um auf die 'MyBean' immer in der gleichen Weise zugreifen zu können, habe ich einfach den' instance' Zugriff überall benutzt. Also muss ich vielleicht meine Frage neu formulieren: Wie kann man eine statische Methode testen und überspielen? – membersound

+1

Keine statischen Singletons verwenden !!! Sie sind böse und böse !!! –

Antwort

0

Wenn Sie die @Bean -creation beeinflussen wollen, dann verwenden Sie @Configuration

@Configuration 
public class MyConfig { 

    @Bean 
    public MyBean myBean() { 
     return new MyBean; 
    } 

    @Bean 
    public OtherService otherService() { 
     return new OtherService(myBean()); 
    } 
} 

Dann wird einfach spöttisch:

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class ITest { 
    @MockBean 
    private MyBean myBean; 

    @Autowired 
    private OtherService service; 

    @Test 
    public void test() { 
     // service is initialised with myBean 
     ... 
    } 
} 
Verwandte Themen