001: // jTDS JDBC Driver for Microsoft SQL Server and Sybase
002: // Copyright (C) 2004 The jTDS Project
003: //
004: // This library is free software; you can redistribute it and/or
005: // modify it under the terms of the GNU Lesser General Public
006: // License as published by the Free Software Foundation; either
007: // version 2.1 of the License, or (at your option) any later version.
008: //
009: // This library is distributed in the hope that it will be useful,
010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: // Lesser General Public License for more details.
013: //
014: // You should have received a copy of the GNU Lesser General Public
015: // License along with this library; if not, write to the Free Software
016: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: //
018: package net.sourceforge.jtds.test;
019:
020: import java.lang.reflect.Constructor;
021: import java.lang.reflect.InvocationTargetException;
022: import java.lang.reflect.Method;
023: import java.lang.reflect.Field;
024:
025: import junit.framework.Assert;
026: import junit.framework.TestCase;
027:
028: import net.sourceforge.jtds.jdbc.Support;
029:
030: /**
031: * Base class for unit tests which do not connect to a database.
032: *
033: * @author David D. Kilzer
034: * @version $Id: UnitTestBase.java,v 1.12 2005/12/22 17:24:07 ddkilzer Exp $
035: */
036: public abstract class UnitTestBase extends TestCase {
037:
038: /**
039: * Constructor.
040: *
041: * @param name The name of the test.
042: */
043: public UnitTestBase(final String name) {
044: super (name);
045: }
046:
047: /**
048: * Invoke a constructor on a class using reflection.
049: *
050: * @param klass The class.
051: * @param classes The classes in the parameter list.
052: * @param objects The objects to be used as parameters.
053: * @return The object constructed.
054: */
055: public static Object invokeConstructor(final Class klass,
056: final Class[] classes, final Object[] objects) {
057: try {
058: Constructor constructor;
059: try {
060: constructor = klass.getDeclaredConstructor(classes);
061: } catch (NoSuchMethodException e) {
062: constructor = klass.getConstructor(classes);
063: }
064: constructor.setAccessible(true);
065: return constructor.newInstance(objects);
066: } catch (NoSuchMethodException e) {
067: RuntimeException runtimeException = new RuntimeException(e
068: .getMessage());
069: Support.linkException(runtimeException, e);
070: throw runtimeException;
071: } catch (InstantiationException e) {
072: RuntimeException runtimeException = new RuntimeException(e
073: .getMessage());
074: Support.linkException(runtimeException, e);
075: throw runtimeException;
076: } catch (IllegalAccessException e) {
077: RuntimeException runtimeException = new RuntimeException(e
078: .getMessage());
079: Support.linkException(runtimeException, e);
080: throw runtimeException;
081: } catch (InvocationTargetException e) {
082: RuntimeException runtimeException = new RuntimeException(e
083: .getTargetException().getMessage());
084: Support.linkException(runtimeException, e);
085: throw runtimeException;
086: }
087: }
088:
089: /**
090: * Get the value of an instance field on an object using reflection.
091: *
092: * @param instance The instance of the object.
093: * @param fieldName The name of the field.
094: * @return The object returned by getting the field.
095: */
096: public static Object invokeGetInstanceField(final Object instance,
097: final String fieldName) {
098: try {
099: Field field;
100: try {
101: field = instance.getClass().getField(fieldName);
102: } catch (NoSuchFieldException e) {
103: field = instance.getClass().getDeclaredField(fieldName);
104: }
105: field.setAccessible(true);
106: return field.get(instance);
107: } catch (NoSuchFieldException e) {
108: RuntimeException runtimeException = new RuntimeException(e
109: .getMessage());
110: Support.linkException(runtimeException, e);
111: throw runtimeException;
112: } catch (IllegalAccessException e) {
113: RuntimeException runtimeException = new RuntimeException(e
114: .getMessage());
115: Support.linkException(runtimeException, e);
116: throw runtimeException;
117: }
118: }
119:
120: /**
121: * Set the value of an instance field on an object using reflection.
122: *
123: * @param instance The instance of the object.
124: * @param fieldName The name of the field.
125: * @param fieldValue The value to set the field to.
126: */
127: public static void invokeSetInstanceField(final Object instance,
128: final String fieldName, final Object fieldValue) {
129: try {
130: Field field;
131: try {
132: field = instance.getClass().getField(fieldName);
133: } catch (NoSuchFieldException e) {
134: field = instance.getClass().getDeclaredField(fieldName);
135: }
136: field.setAccessible(true);
137: field.set(instance, fieldValue);
138: } catch (NoSuchFieldException e) {
139: RuntimeException runtimeException = new RuntimeException(e
140: .getMessage());
141: Support.linkException(runtimeException, e);
142: throw runtimeException;
143: } catch (IllegalAccessException e) {
144: RuntimeException runtimeException = new RuntimeException(e
145: .getMessage());
146: Support.linkException(runtimeException, e);
147: throw runtimeException;
148: }
149: }
150:
151: /**
152: * Invoke an instance method on an object using reflection.
153: *
154: * @param instance The instance of the object.
155: * @param methodName The name of the method.
156: * @param classes The classes in the parameter list.
157: * @param objects The objects to be used as parameters.
158: * @return The object returned by invoking the method.
159: */
160: public static Object invokeInstanceMethod(final Object instance,
161: final String methodName, final Class[] classes,
162: final Object[] objects) {
163:
164: try {
165: Method method;
166: try {
167: method = instance.getClass().getDeclaredMethod(
168: methodName, classes);
169: } catch (NoSuchMethodException e) {
170: method = instance.getClass().getMethod(methodName,
171: classes);
172: }
173: method.setAccessible(true);
174: return method.invoke(instance, objects);
175: } catch (NoSuchMethodException e) {
176: RuntimeException runtimeException = new RuntimeException(e
177: .getMessage());
178: Support.linkException(runtimeException, e);
179: throw runtimeException;
180: } catch (IllegalAccessException e) {
181: RuntimeException runtimeException = new RuntimeException(e
182: .getMessage());
183: Support.linkException(runtimeException, e);
184: throw runtimeException;
185: } catch (InvocationTargetException e) {
186: RuntimeException runtimeException = new RuntimeException(e
187: .getTargetException().getMessage());
188: Support.linkException(runtimeException, e);
189: throw runtimeException;
190: }
191: }
192:
193: /**
194: * Invoke a static method on a class using reflection.
195: *
196: * @param klass The class.
197: * @param methodName The name of the method.
198: * @param classes The classes in the parameter list.
199: * @param objects The objects to be used as parameters.
200: * @return The object returned by invoking the method.
201: */
202: public static Object invokeStaticMethod(final Class klass,
203: final String methodName, final Class[] classes,
204: final Object[] objects) {
205:
206: try {
207: Method method;
208: try {
209: method = klass.getDeclaredMethod(methodName, classes);
210: } catch (NoSuchMethodException e) {
211: method = klass.getMethod(methodName, classes);
212: }
213: method.setAccessible(true);
214: return method.invoke(klass, objects);
215: } catch (NoSuchMethodException e) {
216: RuntimeException runtimeException = new RuntimeException(e
217: .getMessage());
218: Support.linkException(runtimeException, e);
219: throw runtimeException;
220: } catch (IllegalAccessException e) {
221: RuntimeException runtimeException = new RuntimeException(e
222: .getMessage());
223: Support.linkException(runtimeException, e);
224: throw runtimeException;
225: } catch (InvocationTargetException e) {
226: RuntimeException runtimeException = new RuntimeException(e
227: .getTargetException().getMessage());
228: Support.linkException(runtimeException, e);
229: throw runtimeException;
230: }
231: }
232:
233: /**
234: * Compare two arrays element-by-element.
235: * <p/>
236: * The default JUnit {@link Assert#assertEquals(String, Object, Object)} method
237: * does not handle them properly.
238: *
239: * @param message The message to print upon failure.
240: * @param expected The expected value.
241: * @param actual The actual value.
242: */
243: protected void assertEquals(String message, Object[] expected,
244: Object[] actual) {
245:
246: if (expected == null && actual == null) {
247: return;
248: }
249:
250: if (expected == null || actual == null) {
251: failNotEquals(message, expected, actual);
252: }
253:
254: if (expected.length != actual.length) {
255: failNotEquals(message, expected, actual);
256: }
257:
258: for (int i = 0; i < expected.length; i++) {
259: if (expected[i] == null || !expected[i].equals(actual[i])) {
260: failNotEquals(message, expected, actual);
261: }
262: }
263: }
264:
265: /**
266: * @see Assert#failNotEquals(java.lang.String, java.lang.Object, java.lang.Object)
267: */
268: private void failNotEquals(String message, Object[] expected,
269: Object[] actual) {
270: fail((String) invokeStaticMethod(
271: Assert.class,
272: "format",
273: new Class[] { String.class, Object.class, Object.class },
274: new Object[] { message, format(expected),
275: format(actual) }));
276: }
277:
278: /**
279: * Format an <code>Object[]</code> object to a <code>String</code>.
280: *
281: * @param object The object to be formatted.
282: * @return Formatted string representing the object.
283: */
284: private String format(Object[] object) {
285: StringBuffer buf = new StringBuffer();
286: if (object == null || object.length < 1) {
287: buf.append(object);
288: } else {
289: buf.append('{');
290: buf.append(object[0]);
291: for (int i = 1; i < object.length; i++) {
292: buf.append(',');
293: if (object[i] instanceof Object[]) {
294: buf.append(format((Object[]) object[i]));
295: } else {
296: buf.append(object[i]);
297: }
298: }
299: buf.append('}');
300: }
301: return buf.toString();
302: }
303:
304: /**
305: * Changes the first character of a string to uppercase.
306: *
307: * @param s The string to be processed.
308: * @return The value of <code>s</code> if it is <code>null</code> or zero length,
309: * else the string with the first character changed to uppercase.
310: */
311: protected static String ucFirst(String s) {
312: if (s == null || s.length() == 0)
313: return s;
314: if (s.length() == 1) {
315: return s.toUpperCase();
316: }
317: return s.substring(0, 1).toUpperCase() + s.substring(1);
318: }
319:
320: }
|