View Javadoc
1   /*
2    * The Kuali Financial System, a comprehensive financial management system for higher education.
3    * 
4    * Copyright 2005-2014 The Kuali Foundation
5    * 
6    * This program is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Affero General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   * 
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Affero General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Affero General Public License
17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.kuali.kfs.sys;
20  
21  import static junit.framework.Assert.assertEquals;
22  import static junit.framework.Assert.assertFalse;
23  import static junit.framework.Assert.assertNotNull;
24  import static junit.framework.Assert.assertTrue;
25  import static junit.framework.Assert.fail;
26  
27  import java.beans.PropertyDescriptor;
28  import java.lang.reflect.InvocationTargetException;
29  import java.util.Arrays;
30  import java.util.Iterator;
31  import java.util.List;
32  
33  import org.apache.commons.beanutils.PropertyUtils;
34  import org.kuali.rice.krad.bo.BusinessObject;
35  import org.kuali.rice.krad.util.ErrorMessage;
36  import org.kuali.rice.krad.util.GlobalVariables;
37  import org.kuali.rice.krad.util.MessageMap;
38  import org.kuali.rice.krad.util.ObjectUtils;
39  
40  /**
41   * Contains assertion related convenience methods for testing (not for production use).
42   * 
43   * @see org.kuali.rice.kns.util.AssertionUtils
44   */
45  public class KualiTestAssertionUtils {
46  
47  
48      public static void assertEquality(Object a, Object b) {
49          assertNotNull(a);
50          assertNotNull(b);
51  
52          assertTrue(a.equals(b));
53      }
54  
55      public static void assertInequality(Object a, Object b) {
56          assertNotNull(a);
57          assertNotNull(b);
58  
59          assertFalse(a.equals(b));
60      }
61  
62      /**
63       * @see #assertSparselyEqualBean(String, Object, Object)
64       */
65      public static void assertSparselyEqualBean(Object expectedBean, Object actualBean) throws InvocationTargetException, NoSuchMethodException {
66          assertSparselyEqualBean(null, expectedBean, actualBean);
67      }
68  
69      /**
70       * Asserts that the non-null non-BO properties of the expected bean are equal to those of the actual bean. Any null or
71       * BusinessObject expected properties are ignored. Attributes are reflected bean-style via any public no-argument methods
72       * starting with "get" (or "is" for booleans), including inherited methods. The expected and actual beans do not need to be of
73       * the same class.
74       * <p>
75       * Reflection wraps primitives, so differences in primitiveness are ignored. Properties that are BusinessObjects (generally
76       * relations based on foreign key properties) are also ignored, because this method is not testing OJB foreign key resolution
77       * (e.g., via the <code>refresh</code> method), we do not want to have to put all the related BOs into the test fixture
78       * (redundant with the foreign keys), and many (all?) of our BOs implement the <code>equals</code> method in terms of identity
79       * so would fail this assertion anyway. This is a data-oriented assertion, for our data-oriented tests and persistence layer.
80       * 
81       * @param message a description of this test assertion
82       * @param expectedBean a java bean containing expected properties
83       * @param actualBean a java bean containing actual properties
84       * @throws InvocationTargetException if a getter method throws an exception (the cause)
85       * @throws NoSuchMethodException if an expected property does not exist in the actualBean
86       */
87      public static void assertSparselyEqualBean(String message, Object expectedBean, Object actualBean) throws InvocationTargetException, NoSuchMethodException {
88          if (message == null) {
89              message = "";
90          }
91          else {
92              message = message + " ";
93          }
94          assertNotNull(message + "actual bean is null", actualBean);
95          PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(expectedBean);
96          for (int i = 0; i < descriptors.length; i++) {
97              PropertyDescriptor descriptor = descriptors[i];
98              if (PropertyUtils.getReadMethod(descriptor) != null) {
99                  try {
100                     Object expectedValue = PropertyUtils.getSimpleProperty(expectedBean, descriptor.getName());
101                     if (expectedValue != null && !(expectedValue instanceof BusinessObject)) {
102                         assertEquals(message + descriptor.getName(), expectedValue, PropertyUtils.getSimpleProperty(actualBean, descriptor.getName()));
103                     }
104                 }
105                 catch (IllegalAccessException e) {
106                     throw new AssertionError(e); // can't happen because getReadMethod() returns only public methods
107                 }
108             }
109         }
110     }
111 
112     public static void assertGlobalMessageMapContains(String expectedFieldName, String expectedErrorKey) {
113         assertGlobalMessageMapContains("", expectedFieldName, expectedErrorKey, null, true);
114     }
115 
116     public static void assertGlobalMessageMapContains(String message, String expectedFieldName, String expectedErrorKey) {
117         assertGlobalMessageMapContains(message, expectedFieldName, expectedErrorKey, null, true);
118     }
119 
120     public static void assertGlobalMessageMapContains(String expectedFieldName, String expectedErrorKey, String[] expectedErrorParameters) {
121         assertGlobalMessageMapContains("", expectedFieldName, expectedErrorKey, expectedErrorParameters, true);
122     }
123 
124     public static void assertGlobalMessageMapContains(String message, String expectedFieldName, String expectedErrorKey, String[] expectedErrorParameters) {
125         assertGlobalMessageMapContains(message, expectedFieldName, expectedErrorKey, expectedErrorParameters, true);
126     }
127 
128     public static void assertGlobalMessageMapNotContains(String expectedFieldName, String expectedErrorKey) {
129         assertGlobalMessageMapContains("", expectedFieldName, expectedErrorKey, null, false);
130     }
131 
132     public static void assertGlobalMessageMapNotContains(String message, String expectedFieldName, String expectedErrorKey) {
133         assertGlobalMessageMapContains(message, expectedFieldName, expectedErrorKey, null, false);
134     }
135 
136     private static void assertGlobalMessageMapContains(String message, String expectedFieldName, String expectedErrorKey, String[] expectedErrorParameters, boolean contains) {
137         String header = message.length() == 0 ? "" : message + ": ";
138         MessageMap map = GlobalVariables.getMessageMap();
139         assertEquals(header + "no error path (global error map path size)", 0, map.getErrorPath().size());
140         assertEquals(header + "error property '" + expectedFieldName + "' has message key " + expectedErrorKey + ": " + map, contains, map.fieldHasMessage(expectedFieldName, expectedErrorKey));
141 
142         if (contains && expectedErrorParameters != null) {
143             List expectedParameterList = Arrays.asList(expectedErrorParameters);
144             List fieldMessages = map.getMessages(expectedFieldName);
145             if (fieldMessages != null) {
146                 for (Iterator i = fieldMessages.iterator(); i.hasNext();) {
147                     ErrorMessage errorMessage = (ErrorMessage) i.next();
148                     if (sparselyEqualLists(expectedParameterList, Arrays.asList(errorMessage.getMessageParameters()))) {
149                         return; // success;
150                     }
151                 }
152             }
153             fail(header + "error property '" + expectedFieldName + "' message key " + expectedErrorKey + " does not contain expected parameters " + expectedParameterList + ": " + map);
154         }
155     }
156 
157     private static boolean sparselyEqualLists(List expected, List actual) {
158         if (expected.size() != actual.size()) {
159             return false;
160         }
161         Iterator actualIterator = actual.iterator();
162         for (Iterator expectedIterator = expected.iterator(); expectedIterator.hasNext();) {
163             Object expectedItem = expectedIterator.next();
164             Object actualItem = actualIterator.next();
165             if (expectedItem != null && !expectedItem.equals(actualItem)) {
166                 return false;
167             }
168         }
169         return true;
170     }
171 
172     public static void assertGlobalMessageMapEmpty() {
173         assertGlobalMessageMapSize("", 0);
174     }
175 
176     public static void assertGlobalMessageMapEmpty(String message) {
177         assertGlobalMessageMapSize(message, 0);
178     }
179 
180     public static void assertGlobalMessageMapSize(int expectedSize) {
181         assertGlobalMessageMapSize("", expectedSize);
182     }
183 
184     public static void assertGlobalMessageMapSize(String message, int expectedSize) {
185         String header = message.length() == 0 ? "" : message + ": ";
186         MessageMap map = GlobalVariables.getMessageMap();
187         assertEquals(header + "ThreadLocal MessageMap size: " + map, expectedSize, map.getNumberOfPropertiesWithErrors());
188     }
189 
190     /**
191      * Asserts that the given reference is either null or an OJB proxy that references to a nonexistant object. This is different
192      * from assertNull() because ObjectUtils.isNull() checks for OJB proxies and goes to the database to see if real data is
193      * available.
194      * 
195      * @param expectedNull the reference to check
196      */
197     public static void assertNullHandlingOjbProxies(Object expectedNull) {
198         assertNullHandlingOjbProxies(null, expectedNull);
199     }
200 
201     /**
202      * Asserts that the given reference is either null or an OJB proxy that references a nonexistant object. This is different from
203      * assertNotNull() because ObjectUtils.isNull() checks for OJB proxies and goes to the database to see if real data is
204      * available.
205      * 
206      * @param message the context of this assertion, if it fails
207      * @param expectedNull the reference to check
208      */
209     public static void assertNullHandlingOjbProxies(String message, Object expectedNull) {
210         assertTrue(message, ObjectUtils.isNull(expectedNull));
211     }
212 
213     /**
214      * Asserts that the given reference is neither null nor an OJB proxy that references a nonexistant object. This is different
215      * from assertNotNull() because ObjectUtils.isNull() checks for OJB proxies and goes to the database to see if real data is
216      * available.
217      * 
218      * @param expectedNotNull the reference to check
219      */
220     public static void assertNotNullHandlingOjbProxies(Object expectedNotNull) {
221         assertNotNullHandlingOjbProxies(null, expectedNotNull);
222     }
223 
224     /**
225      * Asserts that the given reference is neither null nor an OJB proxy that references a nonexistant object. This is different
226      * from assertNotNull() because ObjectUtils.isNull() checks for OJB proxies and goes to the database to see if real data is
227      * available.
228      * 
229      * @param message the context of this assertion, if it fails
230      * @param expectedNotNull the reference to check
231      */
232     public static void assertNotNullHandlingOjbProxies(String message, Object expectedNotNull) {
233         assertFalse(message, ObjectUtils.isNull(expectedNotNull));
234     }
235 }