/* * Copyright 2008, Unitils.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.unitils.reflectionassert; import junit.framework.TestCase; import static org.unitils.reflectionassert.ReflectionComparatorFactory.createRefectionComparator; import org.unitils.reflectionassert.difference.Difference; import org.unitils.reflectionassert.difference.MapDifference; import static org.unitils.reflectionassert.util.InnerDifferenceFinder.getInnerDifference; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * Test class for {@link ReflectionComparator}. * Contains tests with map types. * * @author Tim Ducheyne * @author Filip Neven */ public class ReflectionComparatorMapTest extends TestCase { /* Test map */ private Map<String, Element> mapA; /* Same as A but different instance */ private Map<String, Element> mapB; /* Same as A and B but different string value for element 2 */ private Map<String, Element> mapDifferentValue; /* Same as A and B but different key value for element 2 */ private Map<String, Element> mapDifferentKey; /* Test map with inner map for element 2 */ private Map<String, Element> mapInnerA; /* Same as innerA but different instance */ private Map<String, Element> mapInnerB; /* Same as innerA and innerB but different string value for inner element 2 */ private Map<String, Element> mapInnerDifferentValue; /* Test map having a key type that returns false for equals() */ private Map<Element, Element> mapReflectionCompareKeyA; /* Same as A but different instance */ private Map<Element, Element> mapReflectionCompareKeyB; /* Same as A and B but with a different key value */ private Map<Element, Element> mapReflectionCompareDifferentKey; /* Class under test */ private ReflectionComparator reflectionComparator; /** * Initializes the test fixture. */ protected void setUp() throws Exception { super.setUp(); mapA = createMap("key 2", "test 2", null); mapB = createMap("key 2", "test 2", null); mapDifferentValue = createMap("key 2", "XXXXXX", null); mapDifferentKey = createMap("XXXXX", "test 2", null); mapInnerA = createMap("key 2", null, mapA); mapInnerB = createMap("key 2", null, mapB); mapInnerDifferentValue = createMap("key 2", null, mapDifferentValue); mapReflectionCompareKeyA = createNotEqualsKeyMap("key 2"); mapReflectionCompareKeyB = createNotEqualsKeyMap("key 2"); mapReflectionCompareDifferentKey = createNotEqualsKeyMap("XXXXXX"); reflectionComparator = createRefectionComparator(); } /** * Test for two equal maps. */ public void testGetDifference_equals() { Difference result = reflectionComparator.getDifference(mapA, mapB); assertNull(result); } /** * Test for two equal maps as an inner field of an object. */ public void testGetDifference_equalsInner() { Difference result = reflectionComparator.getDifference(mapInnerA, mapInnerB); assertNull(result); } /** * Test for two maps that contain different values. */ public void testGetDifference_notEqualsDifferentValues() { Difference result = reflectionComparator.getDifference(mapA, mapDifferentValue); Difference difference = getInnerDifference("string", getInnerDifference("\"key 2\"", result)); assertEquals("test 2", difference.getLeftValue()); assertEquals("XXXXXX", difference.getRightValue()); } /** * Test for two maps that have a different size. The first element was removed from the left map */ public void testGetDifference_notEqualsLeftElementRemoved() { mapA.remove("key 1"); Difference result = reflectionComparator.getDifference(mapA, mapB); assertEquals("key 1", ((MapDifference) result).getRightMissingKeys().get(0)); } /** * Test for two maps that have a different size. The first element was removed from the right map */ public void testGetDifference_notEqualsRightElementRemoved() { mapB.remove("key 1"); Difference result = reflectionComparator.getDifference(mapA, mapB); assertEquals("key 1", ((MapDifference) result).getLeftMissingKeys().get(0)); } /** * Test for objects with inner maps that contain different values. */ public void testGetDifference_notEqualsInnerDifferentValues() { Difference result = reflectionComparator.getDifference(mapInnerA, mapInnerDifferentValue); Difference difference = getInnerDifference("inner", getInnerDifference("\"key 2\"", result)); Difference innerDifference = getInnerDifference("string", getInnerDifference("\"key 2\"", difference)); assertEquals("test 2", innerDifference.getLeftValue()); assertEquals("XXXXXX", innerDifference.getRightValue()); } /** * Test for maps that contain different keys. */ public void testGetDifference_notEqualsDifferentKeys() { Difference result = reflectionComparator.getDifference(mapA, mapDifferentKey); assertSame(mapA, result.getLeftValue()); assertSame(mapDifferentKey, result.getRightValue()); } /** * Tests for objects with inner maps that have a different size. */ public void testGetDifference_notEqualsInnerDifferentSize() { Iterator<?> iterator = mapB.entrySet().iterator(); iterator.next(); iterator.remove(); Difference result = reflectionComparator.getDifference(mapInnerA, mapInnerB); Difference difference = getInnerDifference("inner", getInnerDifference("\"key 2\"", result)); assertSame(mapA, difference.getLeftValue()); assertSame(mapB, difference.getRightValue()); } /** * Tests for maps but right value is not a map. */ public void testGetDifference_notEqualsRightNotMap() { Difference result = reflectionComparator.getDifference(mapA, "Test string"); assertSame(mapA, result.getLeftValue()); assertEquals("Test string", result.getRightValue()); } /** * Tests for equal maps for which the keys are not equals() but are equal using reflection. * The reflection comparator uses strict reflection compare on keys. */ public void testGetDifference_equalsMapComparingKeysUsingReflection() { Difference result = reflectionComparator.getDifference(mapReflectionCompareKeyA, mapReflectionCompareKeyB); assertNull(result); } /** * Tests for using reflection on key values with a different value for one of the keys. * The reflection comparator uses strict reflection compare on keys. */ public void testGetDifference_notEqualsMapComparingKeysUsingReflection() { Difference result = reflectionComparator.getDifference(mapReflectionCompareKeyA, mapReflectionCompareDifferentKey); assertSame(mapReflectionCompareKeyA, result.getLeftValue()); assertSame(mapReflectionCompareDifferentKey, result.getRightValue()); } /** * Creates a map. * * @param keyElement2 the key for the 2nd element in the map * @param stringValueElement2 the value for the 2nd element in the map * @param innerElement2 the value for the inner array of the 2nd element in the map * @return the test map */ private Map<String, Element> createMap(String keyElement2, String stringValueElement2, Map<?, ?> innerElement2) { Map<String, Element> map = new HashMap<String, Element>(); map.put("key 1", new Element("test 1", null)); map.put(keyElement2, new Element(stringValueElement2, innerElement2)); map.put("key 3", new Element("test 3", null)); return map; } /** * Creates a map. * * @param keyElement2 the key for the 2nd element in the map * @return the test map */ private Map<Element, Element> createNotEqualsKeyMap(String keyElement2) { Map<Element, Element> map = new HashMap<Element, Element>(); map.put(new Element("key 1", null), new Element("test 1", null)); map.put(new Element(keyElement2, null), new Element("test 2", null)); return map; } /** * Test class with failing equals. */ private class Element { /* A string value */ private String string; /* An inner map */ private Map<?, ?> inner; /** * Creates and initializes the element. * * @param string the string value * @param inner the inner map */ public Element(String string, Map<?, ?> inner) { this.string = string; this.inner = inner; } /** * Gets the string value * * @return the value */ public String getString() { return string; } /** * Gets the inner map * * @return the map */ public Map<?, ?> getInner() { return inner; } /** * Always returns false * * @param o the object to compare to */ @Override public boolean equals(Object o) { return false; } } }