/* * 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.AssertionFailedError; import org.junit.Test; import java.util.ArrayList; import java.util.List; /** * Tests for correct handling of traversed instances pairs in ReflectionAssert. * <p/> * Special thanks to Dmitry Sidorenko, who first reported this issue and also indicated how to solve it. * * @author Dmitry Sidorenko * @author Tim Ducheyne * @author Filip Neven */ public class ReflectionAssertTraversedInstanceTest { /** * Test comparing objects with two lists which have intersecting list elements * <p/> * When traversing first collection child1 and child2 are marked as already compared. Child1 and child2 were found * not equal, but the reflection assert class only stores the fact that they were already traversed, not the * outcome (not equal). When traversing second collection, child1 and child2 are compared again but because they were * already once compared, they are found equal. Which is ofcourse incorrect. * <p/> * The reflection assert class has been changed to also remember the outcome of traversed instance pairs. */ @Test public void doubleCheckTest() { Parent root1 = new Parent("root"); Parent root2 = new Parent("root"); Parent child1 = new Parent("child1"); Parent child2 = new Parent("child2"); // Adding children in forward order to first root root1.getChildren1().add(child1); root1.getChildren1().add(child2); // Adding children in reverse order to second root root2.getChildren1().add(child2); root2.getChildren1().add(child1); // Adding children in forward order to first root root1.getChildren2().add(child1); root1.getChildren2().add(child2); // Adding children in reverse order to second root root2.getChildren2().add(child2); root2.getChildren2().add(child1); ReflectionAssert.assertLenientEquals(root1, root2); } /** * Test comparing objects with two lists which have intersecting list elements * <p/> * Same as doubleCheckTest(), but showing a case when assert should actually fail, but it doesn't. * This test case is highly dependent on order of fields in collection returned by {@link Class#getDeclaredFields()} */ @Test(expected = AssertionFailedError.class) public void doubleCheckTestShouldFail() { Parent root1 = new Parent("root"); Parent root2 = new Parent("root"); Parent child1 = new Parent("child1"); Parent child2 = new Parent("child2"); // Adding children in forward order to first root root1.getChildren1().add(child1); root1.getChildren1().add(child2); // Adding children in reverse order to second root root2.getChildren1().add(child2); root2.getChildren1().add(child1); // Adding children in forward order to first root root1.getChildren2().add(child1); // Adding children in reverse order to second root root2.getChildren2().add(child2); // Should fail ReflectionAssert.assertLenientEquals(root1, root2); } /** * Test class with to child lists. */ private class Parent { private String name; private List<Parent> children1; private List<Parent> children2; public Parent(String name) { this.name = name; children1 = new ArrayList<Parent>(); children2 = new ArrayList<Parent>(); } public List<Parent> getChildren1() { return children1; } public List<Parent> getChildren2() { return children2; } public String toString() { return name; } } }