阿男的小窝

View the Project on GitHub

RESTEasy与Arquillian的测试集成

下面是使用RESTEasy的integration-tests包与Arquiliian框架创建一个war的例子:

import org.jboss.resteasy.test.resource.param.resource.*;
import org.jboss.resteasy.utils.TestUtil;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.spec.WebArchive;

import java.io.File;

public class CreateWar {
	public static void main(String[] args) {
		WebArchive war = TestUtil.prepareArchive(ParamConverterTest.class.getSimpleName());
		war.addClass(ParamConverterPOJOConverter.class);
		war.addClass(ParamConverterPOJO.class);
		war.addClass(ParamConverterDefaultClient.class);
		war.addClass(ParamConverterClient.class);
		Archive _war = TestUtil.finishContainerPrepare(war, null, ParamConverterPOJOConverterProvider.class,
				ParamConverterResource.class, ParamConverterDefaultResource.class);
		_war.as(ZipExporter.class).exportTo(new File("/tmp/" + _war.getName()), true);
	}
}

上面的代码会在/tmp目录创建一个war文件,内容如下:

$ pwd
/tmp
$ unzip -l ParamConverterTest.war
Archive:  ParamConverterTest.war
  Length      Date    Time    Name
---------  ---------- -----   ----
	 3417  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/utils/TestApplication.class
		0  02-05-2018 14:18   WEB-INF/
		0  02-05-2018 14:18   WEB-INF/classes/
		0  02-05-2018 14:18   WEB-INF/classes/org/
		0  02-05-2018 14:18   WEB-INF/classes/org/jboss/
		0  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/
		0  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/utils/
	 1465  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/resource/param/resource/ParamConverterPOJOConverter.class
		0  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/
		0  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/resource/
		0  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/resource/param/
		0  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/resource/param/resource/
	  625  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/resource/param/resource/ParamConverterPOJO.class
	  313  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/resource/param/resource/ParamConverterDefaultClient.class
	  593  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/resource/param/resource/ParamConverterClient.class
	 1292  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/resource/param/resource/ParamConverterPOJOConverterProvider.class
	 1450  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/resource/param/resource/ParamConverterResource.class
	 1392  02-05-2018 14:18   WEB-INF/classes/org/jboss/resteasy/test/resource/param/resource/ParamConverterDefaultResource.class
	  232  02-05-2018 14:18   WEB-INF/classes/classes.txt
		0  02-05-2018 14:18   WEB-INF/classes/singletons.txt
---------                     -------
	10779                     20 files

注意到TestUtil.finishContainerPrepare(...)方法会创建classes.txtsingletons.txt。以下是这个方法的定义:

/**
 * Finish preparing war deployment and deploy it.
 *
 * Add classes in @resources to deployment. Also all sub-classes of classes in @resources are added to deployment.
 * But only classes in @resources (not sub-classes of classes in @resources) can be used as resources
 * (getClasses function of TestApplication class return only classes in @resources).
 *
 * @param singletons classes used in deployment as singletons
 * @param resources classes used in deployment as resources
 */
public static Archive<?> finishContainerPrepare(WebArchive war, Map<String, String> contextParams, List<Class<?>> singletons, final Class<?>... resources)

可以看到它接受singletonsresources。下面是方法内部的相关实现:

if (resources != null) {
	for (final Class<?> clazz : resources) {
		war.addClass(clazz);
		classNamesInDeployment.add(clazz.getTypeName());
	}
}

if (singletons != null) {
	for (Class<?> singleton : singletons) {
		war.addClass(singleton);
		singletonsNamesInDeployment.add(singleton.getTypeName());
	}
}

可以看到是把classessingletons添加到deployment里面去,这一点和处理其它的classes并没有什么不同。

此外,这些classessingletons会被添加到classes.txtsingletons.txt当中:

war.addAsResource(new StringAsset(classes.toString()), "classes.txt");
war.addAsResource(new StringAsset(singletonBuilder.toString()), "singletons.txt");

这些war里面的txt文件会被TestApplication1读取并加载:

/**
 * Load resources from classes.txt file from deployment
 *
 * @return Array of class names.
 */
public static String[] getClassesFromDeployment(String name) {
	String resource = name + ".txt";
	String stripped = resource.startsWith("/") ?
			resource.substring(1) : resource;

	InputStream stream = null;
	ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
	if (classLoader != null) {
		stream = classLoader.getResourceAsStream(stripped);
	}
	if (stream == null) {
		stream = TestApplication.class.getResourceAsStream(resource);
	}
	if (stream == null) {
		stream = TestApplication.class.getClassLoader().getResourceAsStream(stripped);
	}
	if (stream == null) {
		return new String[0];
	}
	return convertStreamToString(stream).split(",");
}

上面的这个方法会去读区classes.txtsingletons.txt,下面是相关的使用截图:

可以看到,TestApplication会把resources按照classes.txtsingletons.txt里面的内容给读取出来。

下面是TestApplication的class diagram:

下面是TestUtil的class diagram:

以上是对RESTEasy的testsuite的简单分析。

  1. http://docs.jboss.org/resteasy/docs/3.0.24.Final/javadocs/org/jboss/resteasy/utils/TestApplication.html