/* * Copyright (c) 2006 Rogério Liesenfeld * This file is subject to the terms of the MIT license (see LICENSE.txt). */ package mockit; import java.util.*; import org.junit.*; import static org.junit.Assert.*; import mockit.internal.util.*; @SuppressWarnings({ "ObjectEqualsNull", "EqualsBetweenInconvertibleTypes", "FinalizeCalledExplicitly", "SimplifiableJUnitAssertion", "LiteralAsArgToStringEquals", "EqualsWithItself"}) public final class ObjectOverridesTest { @Test public void verifyStandardBehaviorOfOverridableObjectMethodsInMockedInterface( @Mocked Runnable r1, @Mocked Runnable r2) { assertDefaultEqualsBehavior(r1, r2); assertDefaultEqualsBehavior(r2, r1); assertDefaultHashCodeBehavior(r1); assertDefaultHashCodeBehavior(r2); assertDefaultToStringBehavior(r1); assertDefaultToStringBehavior(r2); } void assertDefaultEqualsBehavior(Object obj1, Object obj2) { assertFalse(obj1.equals(null)); assertFalse(obj1.equals("test")); assertTrue(obj1.equals(obj1)); assertFalse(obj1.equals(obj2)); } void assertDefaultHashCodeBehavior(Object obj) { assertEquals(System.identityHashCode(obj), obj.hashCode()); } void assertDefaultToStringBehavior(Object obj) { assertEquals(ObjectMethods.objectIdentity(obj), obj.toString()); } @Test public void verifyStandardBehaviorOfOverriddenObjectMethodsInMockedJREClass(@Mocked Date d1, @Mocked Date d2) { assertDefaultEqualsBehavior(d1, d2); assertDefaultEqualsBehavior(d2, d1); assertDefaultHashCodeBehavior(d1); assertDefaultHashCodeBehavior(d2); assertDefaultToStringBehavior(d1); assertDefaultToStringBehavior(d2); } @Mocked ClassWithObjectOverrides a; @Mocked ClassWithObjectOverrides b; @Before public void callObjectMethodsInMockBeforeEveryTest() { assertEquals(System.identityHashCode(a), a.hashCode()); assertEquals(b, b); } @Test public void verifyStandardBehaviorOfOverriddenObjectMethodsInMockedClass() throws Throwable { assertDefaultEqualsBehavior(a, b); assertDefaultEqualsBehavior(b, a); assertDefaultHashCodeBehavior(a); assertDefaultHashCodeBehavior(b); assertDefaultToStringBehavior(a); assertDefaultToStringBehavior(b); a.finalize(); b.finalize(); } @Test public void mockOverrideOfEqualsMethod() { new Expectations() {{ a.equals(null); result = true; a.equals(anyString); result = true; }}; new Expectations() {{ b.equals(a); result = true; }}; assertTrue(a.equals(null)); assertTrue(a.equals("test")); assertTrue(b.equals(a)); } @Test public void mockOverrideOfHashCodeMethod() { assertTrue(a.hashCode() != b.hashCode()); new Expectations() {{ a.hashCode(); result = 123; b.hashCode(); result = 45; times = 1; }}; assertEquals(123, a.hashCode()); assertEquals(45, b.hashCode()); } @Test public void mockOverrideOfToStringMethod() { assertFalse(a.toString().equals(b.toString())); new Expectations() {{ a.toString(); result = "mocked"; }}; assertTrue("mocked".equals(a.toString())); new Verifications() {{ a.toString(); b.toString(); times = 0; }}; } @Test public void mockOverrideOfCloneMethod() { new Expectations() {{ a.clone(); result = b; }}; assertSame(b, a.clone()); } @Test public void allowAnyInvocationsOnOverriddenObjectMethodsForStrictMocks() { new StrictExpectations() {{ a.getIntValue(); result = 58; b.doSomething(); }}; assertFalse(a.equals(b)); assertTrue(a.hashCode() != b.hashCode()); assertEquals(58, a.getIntValue()); assertTrue(a.equals(a)); String bStr = b.toString(); b.doSomething(); assertFalse(b.equals(a)); String aStr = a.toString(); assertFalse(aStr.equals(bStr)); new Verifications() {{ a.equals(b); b.hashCode(); times = 1; a.toString(); b.equals(null); times = 0; }}; new VerificationsInOrder() {{ a.hashCode(); b.equals(a); }}; } @Test public void recordExpectationsOnOverriddenObjectMethodAsAlwaysNonStrict() { new Expectations() {{ a.doSomething(); a.hashCode(); result = 1; a.equals(any); a.toString(); }}; a.doSomething(); } @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") static class ClassWithEqualsOverride { private final int value; ClassWithEqualsOverride(int value) { this.value = value; } @Override public boolean equals(Object other) { return ((ClassWithEqualsOverride) other).value == value; } } @Test public void mockClassWithEqualsOverrideWhoseInstanceGetsPassedInRecordedStrictExpectation() { final Object o1 = new ClassWithEqualsOverride(123); Object o2 = new ClassWithEqualsOverride(123); new StrictExpectations(ClassWithEqualsOverride.class) {{ a.doSomething(o1); }}; a.doSomething(o2); } @Test public void mockJREClassWithEqualsOverrideWhoseInstanceGetsPassedInRecordedStrictExpectation() { final Object o1 = new Date(123); Object o2 = new Date(123); new StrictExpectations(Date.class) {{ a.doSomething(o1); }}; a.doSomething(o2); } @Test public void callEqualsOnInstanceOfPartiallyMockedClassDuringVerification() { final ClassWithEqualsOverride instance1 = new ClassWithEqualsOverride(1); final ClassWithEqualsOverride instance2 = new ClassWithEqualsOverride(2); new Expectations(ClassWithEqualsOverride.class) {}; new Verifications() {{ assertNotEquals(instance1, instance2); }}; } }