Spring單元測試,內嵌RESTEasy服務的實現

jopen 12年前發布 | 39K 次閱讀 Spring 單元測試

  • RESTEasy介紹

    </li> </ul>

    RESTEasy是JBoss的一個開源項目,提供各種框架幫助你構建RESTful Web Services和RESTful Java應用程序。它是JAX-RS規范的一個完整實現并通過JCP認證。作為一個JBOSS的項目,它當然能和JBOSS應用服務器很好地集成在一起。但是,它也能在任何運行JDK5或以上版本的Servlet容器中運行。RESTEasy還提供一個RESTEasy JAX-RS客戶端調用框架。能夠很方便與EJB、Seam、Guice、Spring和Spring MVC集成使用。支持在客戶端與服務器端自動實現GZIP解壓縮。

    • 內嵌單個服務代碼

      </li> </ul>

      在前面的文章介紹的基礎上,實現SpringJUnit4ClassRunner

      import java.lang.annotation.Annotation;
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      import java.util.Collections;
      import java.util.List;
      
      import org.jboss.resteasy.plugins.server.tjws.TJWSEmbeddedJaxrsServer;
      import org.junit.runner.notification.RunNotifier;
      import org.junit.runners.model.InitializationError;
      import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
      
      public class ResteasyEmbededServer extends SpringJUnit4ClassRunner {
      
          private TJWSEmbeddedJaxrsServer server = new TJWSEmbeddedJaxrsServer();
      
          public ResteasyEmbededServer(Class<?> clazz) throws InitializationError {
              super(clazz);
          }
      
          @Override
          public void run(RunNotifier notifier) {
              int port = findAnnotationValueByClass(Port.class).value();
              Class[] resourceClasses = findAnnotationValueByClass(Resources.class).value();
      
              startServer(port, resourceClasses);
              try {
                  super.run(notifier);
              } finally {
                  server.stop();
              }
          }
      
          private void startServer(int port, Class[] resourceClasses) {
              server.setPort(port);
              List<Class> actualResourceClasses = server.getDeployment().getActualResourceClasses();
              Collections.addAll(actualResourceClasses, resourceClasses);
              server.start();
          }
      
          private <T> T findAnnotationValueByClass(Class<T> annotationClass) {
              for (Annotation annotation : getTestClass().getAnnotations()) {
                  if (annotation.annotationType().equals(annotationClass)) {
                      return (T) annotation;
                  }
              }
              throw new IllegalStateException(String.format("Can't find %s on test class: %s", annotationClass, getTestClass()));
          }
      
          @Retention(RetentionPolicy.RUNTIME)
          @Target(ElementType.TYPE)
          public static @interface Resources {
              public Class[] value();
          }
      
          @Retention(RetentionPolicy.RUNTIME)
          @Target(ElementType.TYPE)
          public static @interface Port {
              public int value();
          }
      
      }
      TJWSEmbeddedJaxrsServer是RESTEasy框架提供的嵌入式服務
      • 使用單個服務

      MockShortMessage.java是Mock發送短信或郵件,CancelAutoOrderTest是測試類

      import javax.ws.rs.Consumes;
      import javax.ws.rs.POST;
      import javax.ws.rs.Path;
      import javax.ws.rs.Produces;
      import javax.ws.rs.core.MediaType;
      import javax.ws.rs.core.Response;
      
      @Path("/mbp/mms/receiver/")
      public class MockShortMessage {
          @POST
          @Consumes(MediaType.APPLICATION_XML)
          @Produces(MediaType.APPLICATION_XML)
          @Path("/shortmsg")
          public Response mobileMessage(ShortMessageDto msg){
              MessageRespDto respDto = new MessageRespDto();
              return Response.ok().entity(respDto).build();
          }
      
          @POST
          @Consumes(MediaType.APPLICATION_XML)
          @Produces(MediaType.APPLICATION_XML)
          @Path("/emailmsg")
          public Response emailMessage(EmailMessageDto msg) {
              MessageRespDto respDto = new MessageRespDto();
              return Response.ok().entity(respDto).build();
          }
      
      
      }
      
      
      
      import javax.ws.rs.core.Response;
      import javax.ws.rs.core.Response.Status;
      
      
      import junit.framework.Assert;
      
      import org.junit.Ignore;
      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.springframework.beans.factory.annotation.Autowired;
      
      
      
      @RunWith(ResteasyEmbededServer.class)
      @ResteasyEmbededServer.Port(8007)
      @ResteasyEmbededServer.Resources({MockShortMessage.class})
      public class CancelAutoOrderTest extends DataPrepareFramework {
      
          @Autowired
          OrderResource orderResource;
      
          @Autowired
          OrderRepository orderRepository;
      
          @Test
          public void should_return_http_status_200_when_cancel_order() {
              Assert.assertEquals("","");
          }
      }

      • 內嵌多個服務代碼

      import java.lang.annotation.Annotation;
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
      import java.util.Map.Entry;
      
      import org.jboss.resteasy.plugins.server.tjws.TJWSEmbeddedJaxrsServer;
      import org.junit.runner.notification.RunNotifier;
      import org.junit.runners.model.InitializationError;
      import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
      
      public class ResteasyMultiEmbededServer extends SpringJUnit4ClassRunner {
      
          private List<TJWSEmbeddedJaxrsServer> servers = new ArrayList<TJWSEmbeddedJaxrsServer>();
      
          public ResteasyMultiEmbededServer(Class<?> clazz) throws InitializationError {
              super(clazz);
          }
      
          @Override
          public void run(RunNotifier notifier) {
              int[] ports = findAnnotationValueByClass(Ports.class).value();
              Class[] resourceClasses = findAnnotationValueByClass(Resources.class).value();
      
              Map<Integer,List<Class>> maps = new HashMap<Integer,List<Class>>();
      
              for(int i=0;i<ports.length;i++){
                  int port = ports[i];
                  if(null==maps.get(port)){
                      maps.put(port,new ArrayList<Class>());
                  }
                  maps.get(port).add(resourceClasses[i]);
              }
              for(Entry<Integer,List<Class>> entry:maps.entrySet()){
                  startServer(new TJWSEmbeddedJaxrsServer(),entry.getKey(),entry.getValue().toArray(new Class[entry.getValue().size()]));
              }
              try {
                  super.run(notifier);
              } finally {
                  for(TJWSEmbeddedJaxrsServer server:servers){
                      server.stop();
                  }
              }
          }
      
          private void startServer(TJWSEmbeddedJaxrsServer server,int port, Class[] resourceClasses) {
              server.setPort(port);
              List<Class> actualResourceClasses = server.getDeployment().getActualResourceClasses();
              Collections.addAll(actualResourceClasses, resourceClasses);
              server.start();
              servers.add(server);
          }
      
          private <T> T findAnnotationValueByClass(Class<T> annotationClass) {
              for (Annotation annotation : getTestClass().getAnnotations()) {
                  if (annotation.annotationType().equals(annotationClass)) {
                      return (T) annotation;
                  }
              }
              throw new IllegalStateException(String.format("Can't find %s on test class: %s", annotationClass, getTestClass()));
          }
      
          @Retention(RetentionPolicy.RUNTIME)
          @Target(ElementType.TYPE)
          public static @interface Resources {
              public Class[] value();
          }
      
          @Retention(RetentionPolicy.RUNTIME)
          @Target(ElementType.TYPE)
          public static @interface Ports {
              public int[] value();
          }
      
      }

      • 使用多個服務

      這里mock了多個服務

      @RunWith(ResteasyMultiEmbededServer.class)
      @ResteasyMultiEmbededServer.Resources({MockCouponResource.class,MockEsbToBookingOrder.class,MockShortMessage.class})
      @ResteasyMultiEmbededServer.Ports({8096,8011,8007})
      public class BookingHotelServiceTest extends DataPrepareFramework{
      
      
          @Test
          public void should_save_coupon_when_booking_and_esb_return_success_given_coupon_and_booking_info() throws Exception{
              Assert.assertEquals("","");
          }
      
      }


 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!