0
|
1 /**
|
|
2 * Originally from http://www.cornetdesign.com/files/BeanTestCase.java.txt
|
|
3 */
|
|
4 package com.five_ten_sg.connectbot.mock;
|
|
5
|
|
6 import junit.framework.TestCase;
|
|
7
|
|
8 import java.lang.reflect.Field;
|
|
9
|
|
10 public class BeanTestCase extends TestCase {
|
|
11
|
|
12 private static final String TEST_STRING_VAL1 = "Some Value";
|
|
13 private static final String TEST_STRING_VAL2 = "Some Other Value";
|
|
14
|
|
15 public static void assertMeetsEqualsContract(Class<?> classUnderTest,
|
|
16 String[] fieldNames) {
|
|
17 Object o1;
|
|
18 Object o2;
|
|
19
|
|
20 try {
|
|
21 // Get Instances
|
|
22 o1 = classUnderTest.newInstance();
|
|
23 o2 = classUnderTest.newInstance();
|
|
24 assertTrue(
|
|
25 "Instances with default constructor not equal (o1.equals(o2))",
|
|
26 o1.equals(o2));
|
|
27 assertTrue(
|
|
28 "Instances with default constructor not equal (o2.equals(o1))",
|
|
29 o2.equals(o1));
|
|
30 Field[] fields = getFieldsByNameOrAll(classUnderTest, fieldNames);
|
|
31
|
|
32 for (int i = 0; i < fields.length; i++) {
|
|
33 // Reset the instances
|
|
34 o1 = classUnderTest.newInstance();
|
|
35 o2 = classUnderTest.newInstance();
|
|
36 Field field = fields[i];
|
|
37 field.setAccessible(true);
|
|
38
|
|
39 if (field.getType() == String.class) {
|
|
40 field.set(o1, TEST_STRING_VAL1);
|
|
41 }
|
|
42 else if (field.getType() == boolean.class) {
|
|
43 field.setBoolean(o1, true);
|
|
44 }
|
|
45 else if (field.getType() == short.class) {
|
|
46 field.setShort(o1, (short) 1);
|
|
47 }
|
|
48 else if (field.getType() == long.class) {
|
|
49 field.setLong(o1, (long) 1);
|
|
50 }
|
|
51 else if (field.getType() == float.class) {
|
|
52 field.setFloat(o1, (float) 1);
|
|
53 }
|
|
54 else if (field.getType() == int.class) {
|
|
55 field.setInt(o1, 1);
|
|
56 }
|
|
57 else if (field.getType() == byte.class) {
|
|
58 field.setByte(o1, (byte) 1);
|
|
59 }
|
|
60 else if (field.getType() == char.class) {
|
|
61 field.setChar(o1, (char) 1);
|
|
62 }
|
|
63 else if (field.getType() == double.class) {
|
|
64 field.setDouble(o1, (double) 1);
|
|
65 }
|
|
66 else if (field.getType().isEnum()) {
|
|
67 field.set(o1, field.getType().getEnumConstants()[0]);
|
|
68 }
|
|
69 else if (Object.class.isAssignableFrom(field.getType())) {
|
|
70 field.set(o1, field.getType().newInstance());
|
|
71 }
|
|
72 else {
|
|
73 fail("Don't know how to set a " + field.getType().getName());
|
|
74 }
|
|
75
|
|
76 assertFalse("Instances with o1 having " + field.getName()
|
|
77 + " set and o2 having it not set are equal", o1
|
|
78 .equals(o2));
|
|
79 field.set(o2, field.get(o1));
|
|
80 assertTrue(
|
|
81 "After setting o2 with the value of the object in o1, the two objects in the field are not equal",
|
|
82 field.get(o1).equals(field.get(o2)));
|
|
83 assertTrue(
|
|
84 "Instances with o1 having "
|
|
85 + field.getName()
|
|
86 + " set and o2 having it set to the same object of type "
|
|
87 + field.get(o2).getClass().getName()
|
|
88 + " are not equal", o1.equals(o2));
|
|
89
|
|
90 if (field.getType() == String.class) {
|
|
91 field.set(o2, TEST_STRING_VAL2);
|
|
92 }
|
|
93 else if (field.getType() == boolean.class) {
|
|
94 field.setBoolean(o2, false);
|
|
95 }
|
|
96 else if (field.getType() == short.class) {
|
|
97 field.setShort(o2, (short) 0);
|
|
98 }
|
|
99 else if (field.getType() == long.class) {
|
|
100 field.setLong(o2, (long) 0);
|
|
101 }
|
|
102 else if (field.getType() == float.class) {
|
|
103 field.setFloat(o2, (float) 0);
|
|
104 }
|
|
105 else if (field.getType() == int.class) {
|
|
106 field.setInt(o2, 0);
|
|
107 }
|
|
108 else if (field.getType() == byte.class) {
|
|
109 field.setByte(o2, (byte) 0);
|
|
110 }
|
|
111 else if (field.getType() == char.class) {
|
|
112 field.setChar(o2, (char) 0);
|
|
113 }
|
|
114 else if (field.getType() == double.class) {
|
|
115 field.setDouble(o2, (double) 1);
|
|
116 }
|
|
117 else if (field.getType().isEnum()) {
|
|
118 field.set(o2, field.getType().getEnumConstants()[1]);
|
|
119 }
|
|
120 else if (Object.class.isAssignableFrom(field.getType())) {
|
|
121 field.set(o2, field.getType().newInstance());
|
|
122 }
|
|
123 else {
|
|
124 fail("Don't know how to set a " + field.getType().getName());
|
|
125 }
|
|
126
|
|
127 if (field.get(o1).equals(field.get(o2))) {
|
|
128 // Even though we have different instances, they are equal.
|
|
129 // Let's walk one of them
|
|
130 // to see if we can find a field to set
|
|
131 Field[] paramFields = field.get(o1).getClass()
|
|
132 .getDeclaredFields();
|
|
133
|
|
134 for (int j = 0; j < paramFields.length; j++) {
|
|
135 paramFields[j].setAccessible(true);
|
|
136
|
|
137 if (paramFields[j].getType() == String.class) {
|
|
138 paramFields[j].set(field.get(o1), TEST_STRING_VAL1);
|
|
139 }
|
|
140 }
|
|
141 }
|
|
142
|
|
143 assertFalse(
|
|
144 "After setting o2 with a different object than what is in o1, the two objects in the field are equal. "
|
|
145 + "This is after an attempt to walk the fields to make them different",
|
|
146 field.get(o1).equals(field.get(o2)));
|
|
147 assertFalse(
|
|
148 "Instances with o1 having "
|
|
149 + field.getName()
|
|
150 + " set and o2 having it set to a different object are equal",
|
|
151 o1.equals(o2));
|
|
152 }
|
|
153 }
|
|
154 catch (InstantiationException e) {
|
|
155 e.printStackTrace();
|
|
156 throw new AssertionError(
|
|
157 "Unable to construct an instance of the class under test");
|
|
158 }
|
|
159 catch (IllegalAccessException e) {
|
|
160 e.printStackTrace();
|
|
161 throw new AssertionError(
|
|
162 "Unable to construct an instance of the class under test");
|
|
163 }
|
|
164 catch (SecurityException e) {
|
|
165 e.printStackTrace();
|
|
166 throw new AssertionError(
|
|
167 "Unable to read the field from the class under test");
|
|
168 }
|
|
169 catch (NoSuchFieldException e) {
|
|
170 e.printStackTrace();
|
|
171 throw new AssertionError(
|
|
172 "Unable to find field in the class under test");
|
|
173 }
|
|
174 }
|
|
175
|
|
176 /**
|
|
177 * @param classUnderTest
|
|
178 * @param fieldNames
|
|
179 * @return
|
|
180 * @throws NoSuchFieldException
|
|
181 */
|
|
182 private static Field[] getFieldsByNameOrAll(Class<?> classUnderTest,
|
|
183 String[] fieldNames) throws NoSuchFieldException {
|
|
184 Field fields[];
|
|
185
|
|
186 if (fieldNames == null) {
|
|
187 fields = classUnderTest.getDeclaredFields();
|
|
188 }
|
|
189 else {
|
|
190 fields = new Field[fieldNames.length];
|
|
191
|
|
192 for (int i = 0; i < fieldNames.length; i++)
|
|
193 fields[i] = classUnderTest.getDeclaredField(fieldNames[i]);
|
|
194 }
|
|
195
|
|
196 return fields;
|
|
197 }
|
|
198
|
|
199 public static void assertMeetsHashCodeContract(Class<?> classUnderTest,
|
|
200 String[] fieldNames) {
|
|
201 try {
|
|
202 Field[] fields = getFieldsByNameOrAll(classUnderTest, fieldNames);
|
|
203
|
|
204 for (int i = 0; i < fields.length; i++) {
|
|
205 Object o1 = classUnderTest.newInstance();
|
|
206 int initialHashCode = o1.hashCode();
|
|
207 Field field = fields[i];
|
|
208 field.setAccessible(true);
|
|
209
|
|
210 if (field.getType() == String.class) {
|
|
211 field.set(o1, TEST_STRING_VAL1);
|
|
212 }
|
|
213 else if (field.getType() == boolean.class) {
|
|
214 field.setBoolean(o1, true);
|
|
215 }
|
|
216 else if (field.getType() == short.class) {
|
|
217 field.setShort(o1, (short) 1);
|
|
218 }
|
|
219 else if (field.getType() == long.class) {
|
|
220 field.setLong(o1, (long) 1);
|
|
221 }
|
|
222 else if (field.getType() == float.class) {
|
|
223 field.setFloat(o1, (float) 1);
|
|
224 }
|
|
225 else if (field.getType() == int.class) {
|
|
226 field.setInt(o1, 1);
|
|
227 }
|
|
228 else if (field.getType() == byte.class) {
|
|
229 field.setByte(o1, (byte) 1);
|
|
230 }
|
|
231 else if (field.getType() == char.class) {
|
|
232 field.setChar(o1, (char) 1);
|
|
233 }
|
|
234 else if (field.getType() == double.class) {
|
|
235 field.setDouble(o1, (double) 1);
|
|
236 }
|
|
237 else if (field.getType().isEnum()) {
|
|
238 field.set(o1, field.getType().getEnumConstants()[0]);
|
|
239 }
|
|
240 else if (Object.class.isAssignableFrom(field.getType())) {
|
|
241 field.set(o1, field.getType().newInstance());
|
|
242 }
|
|
243 else {
|
|
244 fail("Don't know how to set a " + field.getType().getName());
|
|
245 }
|
|
246
|
|
247 int updatedHashCode = o1.hashCode();
|
|
248 assertFalse(
|
|
249 "The field "
|
|
250 + field.getName()
|
|
251 + " was not taken into account for the hashCode contract ",
|
|
252 initialHashCode == updatedHashCode);
|
|
253 }
|
|
254 }
|
|
255 catch (InstantiationException e) {
|
|
256 e.printStackTrace();
|
|
257 throw new AssertionError(
|
|
258 "Unable to construct an instance of the class under test");
|
|
259 }
|
|
260 catch (IllegalAccessException e) {
|
|
261 e.printStackTrace();
|
|
262 throw new AssertionError(
|
|
263 "Unable to construct an instance of the class under test");
|
|
264 }
|
|
265 catch (NoSuchFieldException e) {
|
|
266 e.printStackTrace();
|
|
267 throw new AssertionError(
|
|
268 "Unable to find field in the class under test");
|
|
269 }
|
|
270 }
|
|
271 }
|