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解壓縮。
在前面的文章介紹的基礎上,實現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 {@AutowiredOrderResource orderResource;@AutowiredOrderRepository orderRepository;@Testpublic 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("",""); }}