12637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin/*
22637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin * Copyright (c) 2007 Mockito contributors
32637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin * This program is made available under the terms of the MIT License.
42637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin */
52637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinpackage org.mockito.internal.util.reflection;
62637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
72637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.junit.Test;
82637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockitoutil.TestBase;
92637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
102637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.lang.reflect.Field;
112637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.util.LinkedList;
122637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1308bd32ce48b12ae751dd5c4829ff09a6fb9894f0Philip P. Moltmannimport static org.junit.Assert.assertEquals;
1408bd32ce48b12ae751dd5c4829ff09a6fb9894f0Philip P. Moltmannimport static org.junit.Assert.assertFalse;
152637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.assertj.core.api.Assertions.assertThat;
162637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.mockito.Mockito.*;
172637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
182637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin@SuppressWarnings("unchecked")
192637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinpublic class LenientCopyToolTest extends TestBase {
202637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
212637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private LenientCopyTool tool = new LenientCopyTool();
222637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
232637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    static class InheritMe {
242637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        protected String protectedInherited = "protected";
252637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        private String privateInherited = "private";
262637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
272637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
282637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public static class SomeObject extends InheritMe {
292637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        @SuppressWarnings("unused")
302637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // required because static fields needs to be excluded from copying
312637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        private static int staticField = -100;
322637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        private int privateField = -100;
332637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        private transient int privateTransientField = -100;
342637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        String defaultField = "-100";
352637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        protected Object protectedField = new Object();
362637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public SomeOtherObject instancePublicField = new SomeOtherObject();
372637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        final int finalField;
382637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
392637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public SomeObject(int finalField) {
402637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            this.finalField = finalField;
412637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
422637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
432637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
442637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public static class SomeOtherObject {
452637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
462637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
472637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private SomeObject from = new SomeObject(100);
482637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private SomeObject to = mock(SomeObject.class);
492637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
502637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
512637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldShallowCopyBasicFinalField() throws Exception {
522637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // given
532637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(100, from.finalField);
542637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(to.finalField).isNotEqualTo(100);
552637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
562637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // when
572637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        tool.copyToMock(from, to);
582637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
592637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // then
602637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(100, to.finalField);
612637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
622637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
632637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
642637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldShallowCopyTransientPrivateFields() throws Exception {
652637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // given
662637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.privateTransientField = 1000;
672637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(to.privateTransientField).isNotEqualTo(1000);
682637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
692637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // when
702637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        tool.copyToMock(from, to);
712637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
722637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // then
732637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(1000, to.privateTransientField);
742637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
752637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
762637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
772637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldShallowCopyLinkedListIntoMock() throws Exception {
782637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // given
792637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        LinkedList fromList = new LinkedList();
802637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        LinkedList toList = mock(LinkedList.class);
812637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
822637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // when
832637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        tool.copyToMock(fromList, toList);
842637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
852637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // then no exception is thrown
862637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
872637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
882637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
892637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldShallowCopyFieldValuesIntoMock() throws Exception {
902637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // given
912637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.defaultField = "foo";
922637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.instancePublicField = new SomeOtherObject();
932637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.privateField = 1;
942637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.privateTransientField = 2;
952637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.protectedField = 3;
962637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
972637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(to.defaultField).isNotEqualTo(from.defaultField);
982637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(to.instancePublicField).isNotEqualTo(from.instancePublicField);
992637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(to.privateField).isNotEqualTo(from.privateField);
1002637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(to.privateTransientField).isNotEqualTo(from.privateTransientField);
1012637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(to.protectedField).isNotEqualTo(from.protectedField);
1022637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1032637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // when
1042637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        tool.copyToMock(from, to);
1052637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1062637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // then
1072637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.defaultField, to.defaultField);
1082637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.instancePublicField, to.instancePublicField);
1092637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.privateField, to.privateField);
1102637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.privateTransientField, to.privateTransientField);
1112637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.protectedField, to.protectedField);
1122637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1132637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1142637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
1152637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldCopyValuesOfInheritedFields() throws Exception {
1162637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //given
1172637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        ((InheritMe) from).privateInherited = "foo";
1182637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        ((InheritMe) from).protectedInherited = "bar";
1192637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1202637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(((InheritMe) to).privateInherited).isNotEqualTo(((InheritMe) from).privateInherited);
1212637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1222637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //when
1232637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        tool.copyToMock(from, to);
1242637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1252637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //then
1262637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(((InheritMe) from).privateInherited, ((InheritMe) to).privateInherited);
1272637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1282637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1292637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
1302637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldEnableAndThenDisableAccessibility() throws Exception {
1312637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //given
1322637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        Field privateField = SomeObject.class.getDeclaredField("privateField");
1332637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertFalse(privateField.isAccessible());
1342637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1352637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //when
1362637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        tool.copyToMock(from, to);
1372637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1382637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //then
1392637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        privateField = SomeObject.class.getDeclaredField("privateField");
1402637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertFalse(privateField.isAccessible());
1412637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1422637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1432637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
1442637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldContinueEvenIfThereAreProblemsCopyingSingleFieldValue() throws Exception {
1452637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //given
1462637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        tool.fieldCopier = mock(FieldCopier.class);
1472637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1482637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        doNothing().
1492637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        doThrow(new IllegalAccessException()).
1502637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        doNothing().
1512637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        when(tool.fieldCopier).
1522637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        copyValue(anyObject(), anyObject(), any(Field.class));
1532637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1542637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //when
1552637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        tool.copyToMock(from, to);
1562637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1572637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //then
1582637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        verify(tool.fieldCopier, atLeast(3)).copyValue(any(), any(), any(Field.class));
1592637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1602637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1612637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
1622637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void shouldBeAbleToCopyFromRealObjectToRealObject() throws Exception {
1632637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1642637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // given
1652637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.defaultField = "defaultField";
1662637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.instancePublicField = new SomeOtherObject();
1672637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.privateField = 1;
1682637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.privateTransientField = 2;
1692637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.protectedField = "protectedField";
1702637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        from.protectedInherited = "protectedInherited";
1712637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        to = new SomeObject(0);
1722637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1732637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // when
1742637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        tool.copyToRealObject(from, to);
1752637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1762637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // then
1772637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.defaultField, to.defaultField);
1782637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.instancePublicField, to.instancePublicField);
1792637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.privateField, to.privateField);
1802637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.privateTransientField, to.privateTransientField);
1812637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.protectedField, to.protectedField);
1822637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertEquals(from.protectedInherited, to.protectedInherited);
1832637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1842637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1852637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin}
186