Sunday 15 June 2008

Java私有方法的测试

Java世界里最臭名昭著私有方法估计就是类java.io.ObjectInputStream里的`latestUserDefinedLoader'。这个方法的行为多少有点让人捉摸不透。这个类还是一个私有的、本地的方法(private, native)。

下面两个方法使`latestUserDefinedLoader'的测试变得容易:
,----[ Class LatestUserDefinedLoaderUtil ]
| public static ClassLoader latestUserDefinedLoader() throws Exception {
| ClassLoader latestUserDefinedLoader = (ClassLoader) invokeStaticMethod(
| ObjectInputStream.class, "latestUserDefinedLoader");
| return latestUserDefinedLoader;
| }
|
| public static Object invokeStaticMethod(Class klass, String name)
| throws Exception {
| Method method = klass.getDeclaredMethod(name, new Class[0]);
| method.setAccessible(true);
| return method.invoke(null, null);
| }
`----
为了测试latestUserDefinedLoader的行为,再增加两个方法:
,----[ Class LatestUserDefinedLoaderUtil Continue ]
| public static String getClassName() {
| return LatestUserDefinedLoaderUtil.class.getName();
| }
|
| public static URL getResource() throws Exception {
| String resName = getClassName().replace('.', '/') + ".class";
| String resource = Thread.currentThread().getContextClassLoader().getResource(resName).toString();
| return new URL(resource.substring(0, resource.indexOf(resName)));
| }
`----
下面是一个不那么复杂的测试用例:
,----
| public void testLatestUserDefinedLoader() throws Exception {
| URL[] urls = new URL[1];
| urls[0] = LatestUserDefinedLoaderUtil.getResource();
| System.out.println(urls[0]);
| ClassLoader classLoader = new URLClassLoader(urls, null);
| Class klass = LatestUserDefinedLoaderUtil.class;
| Class theKlass = classLoader.loadClass(LatestUserDefinedLoaderUtil.getClassName());
| assertNotNull(theKlass);
| ClassLoader latestUserDefinedLoader = (ClassLoader)
| LatestUserDefinedLoaderUtil.invokeStaticMethod(theKlass, "latestUserDefinedLoader");
| assertEquals(classLoader, latestUserDefinedLoader);
| }
`----

No comments: