001/* 002 * #%L 003 * Netarchivesuite - common - test 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023package dk.netarkivet.testutils; 024 025import static org.junit.Assert.assertEquals; 026 027import java.lang.reflect.Constructor; 028import java.lang.reflect.Field; 029import java.lang.reflect.Method; 030 031import org.junit.Assert; 032 033/** 034 * Methods that help in doing common reflection tasks. 035 */ 036public class ReflectUtils { 037 /** 038 * Look up a private method and make it accessible for testing. 039 * 040 * @param c Class to look in. 041 * @param name Name of the method. 042 * @param args Arguments for the method. Note that primitive types are found using XXX.TYPE. 043 * @return Method object, accessible for calling. 044 * @throws NoSuchMethodException 045 */ 046 public static Method getPrivateMethod(Class<?> c, String name, Class<?>... args) throws NoSuchMethodException { 047 Method m = c.getDeclaredMethod(name, args); 048 m.setAccessible(true); 049 return m; 050 } 051 052 /** 053 * Look up a private field and make it accessible for testing. 054 * 055 * @param c The class that declares the field. 056 * @param fieldName The name of the field. 057 * @return The field, which can now be set. 058 * @throws NoSuchFieldException If there is no such field declared in the class. 059 */ 060 public static <T> Field getPrivateField(Class<?> c, String fieldName) throws NoSuchFieldException { 061 Field f = c.getDeclaredField(fieldName); 062 f.setAccessible(true); 063 return f; 064 } 065 066 /** 067 * Look up a private constructor and make it accessible for testing. 068 * 069 * @param c Class to look in. 070 * @param args Arguments for the constructor. Note that primitive types are found using XXX.TYPE. 071 * @return Constructor object, accessible for calling. 072 * @throws NoSuchMethodException 073 */ 074 public static <T> Constructor<T> getPrivateConstructor(Class<T> c, Class<?>... args) throws NoSuchMethodException { 075 Constructor<T> con = c.getDeclaredConstructor(args); 076 con.setAccessible(true); 077 return con; 078 } 079 080 /** 081 * Method for testing the constructor of a utility class (the constructor should be private). 082 */ 083 @SuppressWarnings({"rawtypes"}) 084 public static void testUtilityConstructor(Class c) { 085 Constructor[] constructors = c.getConstructors(); 086 087 assertEquals("There should be no public constructors.", 0, constructors.length); 088 089 constructors = c.getDeclaredConstructors(); 090 assertEquals("There should be one constructor.", 1, constructors.length); 091 092 for (Constructor con : constructors) { 093 Assert.assertFalse("The constructor should not be accessible.", con.isAccessible()); 094 095 con.setAccessible(true); 096 Assert.assertTrue("The constructor should now be accessible.", con.isAccessible()); 097 098 try { 099 Object instance = con.newInstance((Object[]) null); 100 Assert.assertNotNull("It should be possible to instatiate now.", instance); 101 } catch (Throwable e) { 102 e.printStackTrace(); 103 Assert.fail(e.getMessage()); 104 } 105 } 106 } 107}