2015-04-17 7 views
7

Я прочитал много руководств по работе с службами Spring Boot и RESTful, и многие из них содержат информацию о выполнении модульных тестов, в первую очередь «Создание приложения с помощью Spring Boot». Тем не менее, я не видел ничего, что дает пример того, как выполнить модульное тестирование приложения Spring Boot, которое потребляет/зависит от других приложений Spring Boot, как это обычно бывает в облачной архитектуре микросервисов. Так, например, мы имеем следующие Spring Загрузочные услуги:Тестирование интеграции Spring Boot based Microservices

ServiceMediator, Adapter1, Adapter2

ServiceMediator называет Adapter1 или Adapter2, в зависимости от входного сигнала.

Есть ли способ запустить службы Spring Boot Adapter1 и Adapter2 перед запуском и тестированием ServiceMediator в тесте Spring JUnit?

+0

ARE YOU что вы будете издеваться над ServiceMediator или хотите провести интеграционный тест относительно того, где вы называете реальный сервис? – ndrone

+0

Интеграционное тестирование - это то, о чем я говорю. – LouRoy

+0

Я думаю, это зависит от того, как вы его определяете. Я просто ищу способ проверить все службы на моей локальной машине автоматическим способом. Следовательно, есть ли способ запуска сервисов, который посредник зависит от тестирования посредника? – LouRoy

ответ

1
package controller; 


import static org.junit.Assert.assertThat; 

import java.io.File; 
import java.net.URL; 

import mediator.CLPApplication; 

import org.hamcrest.Matchers; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.boot.test.IntegrationTest; 
import org.springframework.boot.test.SpringApplicationConfiguration; 
import org.springframework.boot.test.TestRestTemplate; 
import org.springframework.http.ResponseEntity; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.web.WebAppConfiguration; 
import org.springframework.web.client.RestClientException; 
import org.springframework.web.client.RestTemplate; 

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = CLPApplication.class) 
@WebAppConfiguration 
@IntegrationTest() 
public class ControllerTest { 

    @Value("${adapter.dependency.jar.location}") 
    private String adapterDependencyJarLocation; 

    @Value("${adapter.dependency.jar.name}") 
    private String adapterDependencyJarName; 

    @Value("${adapter.url}") 
    private String adapterURL; 

    @Value("${mediator.url}") 
    private String mediatorURL; 

    private URL mediator; 
    private URL adapter; 
    private RestTemplate template; 
    Process process = null; 

    @Before 
    public void setUp() throws Exception { 

     adapter = new URL(adapterURL); 
     template = new TestRestTemplate(); 

     // 
     // Start the Atomic adapter 
     // 
     System.out.println(adapterDependencyJarLocation); 
     System.out.println("Starting Adapter"); 

     try { 
      process = new ProcessBuilder("java", "-jar", adapterDependencyJarName) 
       .directory(new File(adapterDependencyJarLocation)).start(); 

      // Try connecting 5 times with a 5 second pause between each 
      // to see if it started. 
      Thread.sleep(5000); 
      for(int i = 0; i <= 5; i++) { 
       try{ 
        System.out.println("Testing to see if Adapter is up"); 
        template.getForEntity(adapter.toString(), String.class); 
        System.out.println("Adapter Started"); 
        break; 
       } 
       catch(RestClientException rce){ 
        System.out.println("It's not up yet"); 
       } 
       Thread.sleep(5000); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    @Test 
    public void testMediator() throws Exception { 
     mediator = new URL(mediatorURL); 
     System.out.println("Calling Mediator"); 
     ResponseEntity<String> response = template.getForEntity(mediator.toString(), String.class); 
     System.out.println(response.getBody()); 
     // Getting back JSON, so check to see if it starts with an open bracket 
     assertThat(response.getBody(), Matchers.startsWith("{")); 
    } 

    @After 
    public void tearDown() { 
     if(process != null) { 
      process.destroy(); 
     } 
    } 
} 
4

process-exec-maven-plugin может быть полезным, поскольку позволяет запускать несколько процессов Java на предварительном интеграционном тесте фазы (как стандартные приложения Spring загрузочных), и он автоматически заботится о закрывая их в пост- интеграция-тест фаза.

Примечание: Тест интеграции должен быть запущен на интеграции испытаний фазы для что Maven-безотказное-плагин должен быть сконфигурирован с пружинными загрузки Maven-плагинsee. Затем запустить наши интеграционные тесты проверить или выше Maven Lifecycle должна быть направлены, потому что интеграции теста фаза на самом деле находятся между пакетом и проверитьsee Default Lifecycles жизненных циклов.

Следующая Maven (pom.xml) конфигурация работала для меня:

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-maven-plugin</artifactId> 
      <version>1.3.5.RELEASE</version> 
      <executions>      
       <execution> 
        <id>pre-integration-test</id> 
        <goals> 
         <goal>start</goal> 
        </goals> 
        <configuration> 
         <skip>${integration-tests.skip}</skip> 
        </configuration> 
       </execution> 
       <execution> 
        <id>post-integration-test</id> 
        <goals> 
         <goal>stop</goal> 
        </goals> 
        <configuration> 
         <skip>${integration-tests.skip}</skip> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin>   

     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-failsafe-plugin</artifactId> 
      <version>2.19.1</version> 
      <configuration> 
       <skip>${integration-tests.skip}</skip>     
       <includes> 
        <include>**/*IT.java</include> 
       </includes> 
      </configuration> 
      <executions> 
       <execution> 
        <goals> 
         <goal>integration-test</goal> 
         <goal>verify</goal> 
        </goals>       
       </execution>      
      </executions> 
     </plugin> 

     <plugin> 
      <groupId>com.bazaarvoice.maven.plugins</groupId> 
      <artifactId>process-exec-maven-plugin</artifactId> 
      <version>0.7</version> 
      <executions>      
       <execution> 
        <id>switchboard-process</id> 
        <phase>pre-integration-test</phase> 
        <goals> 
         <goal>start</goal> 
        </goals> 
        <configuration> 
         <name>accounts-service</name> 
         <workingDir>/../../micro-service</workingDir> 
         <waitForInterrupt>false</waitForInterrupt>       
         <arguments> 
          <argument>java</argument> 
          <argument>-jar</argument> 
          <argument>${basedir}/../micro-service/target/micro-service-${project.version}-exec.jar</argument> 
         </arguments> 
        </configuration> 
       </execution> 
       <!--Stop all processes in reverse order--> 
       <execution> 
        <id>stop-all</id> 
        <phase>post-integration-test</phase> 
        <goals> 
         <goal>stop-all</goal> 
        </goals> 
       </execution> 
      </executions> 
     </plugin> 
    </plugins> 
</build> 

Имея класс Integration Test (WebServerIT) в Test.java папку:

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = WebServerApp.class) 
@WebIntegrationTest("server.port:0") 
public class WebServerIT { 

    @Autowired 
    private WebApplicationContext webServerAppContext; 

    private MockMvc webServerMockMvc; 

    @Before 
    public void setUp() { 
     System.out.println("the test is set up"); 
     webServerMockMvc = MockMvcBuilders.webAppContextSetup(webServerAppContext).build(); 
    } 

    /** 
    * This test calls the WebServer's endpoint (/accounts/123456789) which in turn calls the micro-service rest api 
    * which is started using the process-exec-maven-plugin, otherwise the test would fail. 
    */ 
    @Test 
    public void testWebServerInteractionWithMicroService() throws Exception { 
     this.webServerMockMvc.perform(get("/accounts/123456789")) 
       .andExpect(status().isOk()); 
    } 
} 
Смежные вопросы