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

}





Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐