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

  • RESTEasy介紹

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 {

	@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("","");
    }

}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章