2015-09-28 1 views
9

Ich versuche, einen Test für dieses Java SpringBoot Klasse zu schreiben:Mock-Objekt Methodenaufruf mit Spring-Boot und Mockito

https://github.com/callistaenterprise/blog-microservices/blob/master/microservices/composite/product-composite-service/src/main/java/se/callista/microservices/composite/product/service/ProductCompositeIntegration.java

Insbesondere Ich versuche, diese Methode Aufruf "mock" :

URI uri = util.getServiceUrl("product"); 

ich fand heraus, ich „Mock“ die ServiceUtils Objekt, um dies tun sollte. Ich habe versucht, diese mit den @Mock und @InjectMocks Anmerkungen:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = ProductCompositeServiceApplication.class) 
public class ProductCompositeIntegrationTest { 

    @InjectMocks 
    @Autowired 
    private ProductCompositeIntegration productIntegration; 

    @Autowired 
    private RestTemplate restTemplate; 

    @Mock 
    private ServiceUtils util; 

    private MockRestServiceServer mockServer; 

    @Before 
    public void setUp() { 
     MockitoAnnotations.initMocks(this); 
     mockServer = MockRestServiceServer.createServer(restTemplate); 
    } 

    @Test 
    public void myTest() { 
     Mockito.when(util.getServiceUrl("product")).thenReturn(URI.create("http://localhost:8080/test")); 
     ResponseEntity<Iterable<Product>> products = productIntegration.getAllProducts(); 
    } 
} 

Aber auf diese Weise es immer noch das ursprüngliche ServiceUtils Objekt aufruft, und nicht die „verspottet“ ein. Auch ohne die @Autowired Annotation an der ProductCompositeIntegration versucht, aber dies ergibt eine NullPointerException.

Was mache ich falsch?


Meine Haupt Klasse sieht wie folgt aus:

@SpringBootApplication 
@EnableCircuitBreaker 
@EnableDiscoveryClient 
public class ProductCompositeServiceApplication { 
    public static void main(String[] args) { 
     SpringApplication.run(ProductCompositeServiceApplication.class, args); 
    } 
} 

Das ServiceUtils Objekt, das ich zu verspotten versuchen in einer Klasse angegeben, kommentierte mit Spring @Component Anmerkung es in die anderen Klassen zu injizieren @Autowired mit .

Antwort

7

Nach viel Versuch und Irrtum gelang es mir, dieses Problem zu lösen.

Ich ließ die

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = ProductCompositeServiceApplication.class) 

Anmerkungen der Testklasse aboved.

ich markierte die Klasse, die ich mit @InjectMocks und den Abhängigkeiten mit @Mock Prüfung wurde:

public class ProductCompositeIntegrationTest { 
    @InjectMocks 
    private ProductCompositeIntegration productIntegration; 

    @Mock 
    private ServiceUtils util; 

    private MockRestServiceServer mockServer; 

    private RestTemplate restTemplate = new RestTemplate(); 

    @Before 
    public void init() { 
     MockitoAnnotations.initMocks(this); 
     mockServer = MockRestServiceServer.createServer(restTemplate); 
     productIntegration.setRestTemplate(restTemplate); 
    } 

    @Test 
    public void someTests() { 
     when(util.getServiceUrl("product")).thenReturn(URI.create("http://localhost:8080/test")); 
     //Test code... 
    } 
} 

Ich bin mir nicht sicher, ob dies der beste Ansatz („der Frühlings-Weg“), aber das war für mich.

Dieser Artikel machte es mir klar: http://rdafbn.blogspot.be/2014/01/testing-spring-components-with-mockito.html

+1

Ich mochte Ihren Ansatz. Es war genau das, wonach ich suchte. – user2957378

0

Sie haben eine FactoryBean wie

public class MockitoFactoryBean<T> implements FactoryBean<T> { 

private Class<T> classToBeMocked; 

public MockitoFactoryBean(Class<T> classToBeMocked) { 
    this.classToBeMocked = classToBeMocked; 
} 


@Override 
public T getObject() throws Exception { 
    return Mockito.mock(classToBeMocked); 
} 

@Override 
public Class<?> getObjectType() { 
    return classToBeMocked; 
} 

@Override 
public boolean isSingleton() { 
    return true; 
} 
} 

In Ihrem schreiben test-context.xml Sie haben die folgenden Zeilen hinzuzufügen.

Wenn Sie keine XML-Konfiguration verwenden, müssen Sie das Äquivalent zu oben in Ihrer Java-Konfiguration hinzufügen.

+0

Muss ich etwas in die Klasse ändern, die getestet werden muss? Ich habe versucht, das ServiceUtils-Objekt in der Test-Klasse mit dieser Factory zu instanziieren, aber das Ergebnis ist das gleiche @Mock private ServiceUtils util = factoryBean.getObject(); – Kaj

+0

Sie müssen die FactoryBean in Ihrer test-context.xml hinzufügen. Ich habe die Antwort bearbeitet. –