2015-12-03 24 views
21

ich eine Klasse A haben dieWie @InjectMocks verwenden zusammen mit @Autowired Annotation in Junit

public class A() { 

    @Autowired 
    private B b; 

    @Autowired 
    private C c; 

    @Autowired 
    private D d; 
} 

Beim Testen sie mit autowiring 3 differnt Klassen verwendet, würde ich nur 2 der Klassen haben möchte (B & C) als Mocks und haben Klasse D Autowired als normaler Lauf werden, dieser Code funktioniert nicht für mich:

@RunWith(MockitoJUnitRunner.class) 
public class aTest() { 

    @InjectMocks 
    private A a; 

    @Mock 
    private B b; 

    @Mock 
    private C c; 

    @Autowired 
    private D d; 
} 

ist es überhaupt möglich, dies zu tun?

Antwort

21

Es sollte so etwas wie

@RunWith(SpringJUnit4ClassRunner.class) 
public class aTest() { 

    @Mock 
    private B b; 

    @Mock 
    private C c; 

    @Autowired 
    @InjectMocks 
    private A a; 

} 

sein Wenn Sie D wollen Autowired sein müssen, nicht Ihre Test Klasse tun, was in. Ihre AutowiredA sollte korrekte Instanz von haben. Auch ich denke, Sie müssen SpringJUnit4ClassRunner für Autowiring arbeiten, mit contextConfiguration richtig eingestellt. Weil Sie nicht MockitoJunitRunner verwenden müssen Sie Ihre mocks selbst

MockitoAnnotations.initMocks (java.lang.Object Testclass)

+0

Gibt es eine Möglichkeit, @RunWith (MockitoJUnitRunner.class) weiter zu verwenden und dieses Problem zu lösen? Der obige Code ist nur ein Teil der größeren Test-Klasse, und ich kann nicht ändern, wie wir junits laufen – USer22999299

+1

Ja können Sie, aber Sie können nicht 'Autowired' in diesem Fall verwenden, dann müssen Sie manuell Code initialisieren Feder Kontext laden die Instanz von 'A' –

+2

Es gibt einen Fall, in dem dieser Ansatz nicht funktioniert: wenn' A' mit '@Transactional' versehen ist (oder Methoden mit' @Transactional' versehen sind); siehe http://stackoverflow.com/questions/12857981/transactional-annota-avoids-services-being-mocked und http://stackoverflow.com/questions/21124326/how-to-inject-mock-into-service-that -has-transactional –

2

Ich war mit Blick auf gleiche Problem mit initialisieren und versucht, die Antwort von Sajan Dran . In meinem Fall hat es nicht funktioniert, da ich @ SpringBootTest Annotation verwende, um nur eine Teilmenge aller meiner Beans zu laden. Das Ziel ist nicht, die Beans zu laden, die ich verspotte, da sie viele andere Abhängigkeiten und Konfigurationen haben.

Und ich fand für mich die folgende Variante der Lösung, die auch im Normalfall verwendbar ist.

@RunWith(SpringRunner.class) 
@SpringBootTest(classes={...classesRequired...}) 
public class aTest() { 

    @Mock 
    private B b; 

    @Mock 
    private C c; 

    @Autowired 
    @Spy 
    private D d; 

    @InjectMocks 
    private A a; 

    @Before 
    public void init(){ 
     MockitoAnnotations.initMocks(this); 
    } 

} 
Verwandte Themen