blob: 04e960076b57a0ee06d72e7409a50844c3f2df72 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska24c849c2014-10-27 09:53:05 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska24c849c2014-10-27 09:53:05 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
Pavlin Radoslavovd26f57a2014-10-23 17:19:45 -070016package org.onlab.junit;
Jonathan Hart20d8e512014-10-16 11:05:52 -070017
18import java.lang.reflect.Constructor;
19import java.lang.reflect.Field;
20import java.lang.reflect.InvocationTargetException;
21import java.lang.reflect.Method;
22
23
24/**
25 * Utilities for testing.
26 */
27public final class TestUtils {
28
29 /**
30 * Sets the field, bypassing scope restriction.
31 *
32 * @param subject Object where the field belongs
33 * @param fieldName name of the field to set
34 * @param value value to set to the field.
35 * @param <T> subject type
36 * @param <U> value type
37 * @throws TestUtilsException if there are reflection errors while setting
38 * the field
39 */
40 public static <T, U> void setField(T subject, String fieldName, U value)
41 throws TestUtilsException {
42 @SuppressWarnings("unchecked")
43 Class<T> clazz = (Class<T>) subject.getClass();
44 try {
45 Field field = clazz.getDeclaredField(fieldName);
46 field.setAccessible(true);
47 field.set(subject, value);
48 } catch (NoSuchFieldException | SecurityException |
49 IllegalArgumentException | IllegalAccessException e) {
50 throw new TestUtilsException("setField failed", e);
51 }
52 }
53
54 /**
55 * Gets the field, bypassing scope restriction.
56 *
57 * @param subject Object where the field belongs
58 * @param fieldName name of the field to get
59 * @return value of the field.
60 * @param <T> subject type
61 * @param <U> field value type
62 * @throws TestUtilsException if there are reflection errors while getting
63 * the field
64 */
65 public static <T, U> U getField(T subject, String fieldName)
66 throws TestUtilsException {
67 try {
68 @SuppressWarnings("unchecked")
69 Class<T> clazz = (Class<T>) subject.getClass();
70 Field field = clazz.getDeclaredField(fieldName);
71 field.setAccessible(true);
72
73 @SuppressWarnings("unchecked")
74 U result = (U) field.get(subject);
75 return result;
76 } catch (NoSuchFieldException | SecurityException |
77 IllegalArgumentException | IllegalAccessException e) {
78 throw new TestUtilsException("getField failed", e);
79 }
80 }
81
82 /**
83 * Calls the method, bypassing scope restriction.
84 *
85 * @param subject Object where the method belongs
86 * @param methodName name of the method to call
87 * @param paramTypes formal parameter type array
88 * @param args arguments
89 * @return return value or null if void
90 * @param <T> subject type
91 * @param <U> return value type
92 * @throws TestUtilsException if there are reflection errors while calling
93 * the method
94 */
95 public static <T, U> U callMethod(T subject, String methodName,
96 Class<?>[] paramTypes, Object...args) throws TestUtilsException {
97
98 try {
99 @SuppressWarnings("unchecked")
100 Class<T> clazz = (Class<T>) subject.getClass();
101 final Method method;
102 if (paramTypes == null || paramTypes.length == 0) {
103 method = clazz.getDeclaredMethod(methodName);
104 } else {
105 method = clazz.getDeclaredMethod(methodName, paramTypes);
106 }
107 method.setAccessible(true);
108
109 @SuppressWarnings("unchecked")
110 U result = (U) method.invoke(subject, args);
111 return result;
112 } catch (NoSuchMethodException | SecurityException |
113 IllegalAccessException | IllegalArgumentException |
114 InvocationTargetException e) {
115 throw new TestUtilsException("callMethod failed", e);
116 }
117 }
118
119 /**
120 * Calls the method, bypassing scope restriction.
121 *
122 * @param subject Object where the method belongs
123 * @param methodName name of the method to call
124 * @param paramType formal parameter type
125 * @param arg argument
126 * @return return value or null if void
127 * @param <T> subject type
128 * @param <U> return value type
129 * @throws TestUtilsException if there are reflection errors while calling
130 * the method
131 */
132 public static <T, U> U callMethod(T subject, String methodName,
133 Class<?> paramType, Object arg) throws TestUtilsException {
134 return callMethod(subject, methodName, new Class<?>[]{paramType}, arg);
135 }
136
137 /**
138 * Triggers an allocation of an object of type <T> and forces a call to
139 * the private constructor.
140 *
141 * @param constructor Constructor to call
142 * @param <T> type of the object to create
Thomas Vachuska8cd66a52014-10-30 11:53:07 -0700143 * @return created object of type T
Jonathan Hart20d8e512014-10-16 11:05:52 -0700144 * @throws TestUtilsException if there are reflection errors while calling
145 * the constructor
146 */
147 public static <T> T callConstructor(Constructor<T> constructor)
148 throws TestUtilsException {
149 try {
150 constructor.setAccessible(true);
151 return constructor.newInstance();
152 } catch (InstantiationException | IllegalAccessException |
153 InvocationTargetException error) {
154 throw new TestUtilsException("callConstructor failed", error);
155 }
156 }
157
158 /**
159 * Avoid instantiation.
160 */
161 private TestUtils() {}
162
163 /**
164 * Exception that can be thrown if problems are encountered while executing
165 * the utility method. These are usually problems accessing fields/methods
166 * through reflection. The original exception can be found by examining the
167 * cause.
168 */
169 public static class TestUtilsException extends Exception {
170
171 private static final long serialVersionUID = 1L;
172
173 /**
174 * Constructs a new exception with the specified detail message and
175 * cause.
176 *
177 * @param message the detail message
178 * @param cause the original cause of this exception
179 */
180 public TestUtilsException(String message, Throwable cause) {
181 super(message, cause);
182 }
183 }
184}