/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.util.reflection;
import org.junit.Test;
import org.mockitoutil.TestBase;
import java.lang.reflect.Field;
import java.util.LinkedList;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
@SuppressWarnings("unchecked")
public class LenientCopyToolTest extends TestBase {
private LenientCopyTool tool = new LenientCopyTool();
static class InheritMe {
protected String protectedInherited = "protected";
private String privateInherited = "private";
}
public static class SomeObject extends InheritMe {
@SuppressWarnings("unused")
// required because static fields needs to be excluded from copying
private static int staticField = -100;
private int privateField = -100;
private transient int privateTransientField = -100;
String defaultField = "-100";
protected Object protectedField = new Object();
public SomeOtherObject instancePublicField = new SomeOtherObject();
final int finalField;
public SomeObject(int finalField) {
this.finalField = finalField;
}
}
public static class SomeOtherObject {
}
private SomeObject from = new SomeObject(100);
private SomeObject to = mock(SomeObject.class);
@Test
public void shouldShallowCopyBasicFinalField() throws Exception {
// given
assertEquals(100, from.finalField);
assertThat(to.finalField).isNotEqualTo(100);
// when
tool.copyToMock(from, to);
// then
assertEquals(100, to.finalField);
}
@Test
public void shouldShallowCopyTransientPrivateFields() throws Exception {
// given
from.privateTransientField = 1000;
assertThat(to.privateTransientField).isNotEqualTo(1000);
// when
tool.copyToMock(from, to);
// then
assertEquals(1000, to.privateTransientField);
}
@Test
public void shouldShallowCopyLinkedListIntoMock() throws Exception {
// given
LinkedList fromList = new LinkedList();
LinkedList toList = mock(LinkedList.class);
// when
tool.copyToMock(fromList, toList);
// then no exception is thrown
}
@Test
public void shouldShallowCopyFieldValuesIntoMock() throws Exception {
// given
from.defaultField = "foo";
from.instancePublicField = new SomeOtherObject();
from.privateField = 1;
from.privateTransientField = 2;
from.protectedField = 3;
assertThat(to.defaultField).isNotEqualTo(from.defaultField);
assertThat(to.instancePublicField).isNotEqualTo(from.instancePublicField);
assertThat(to.privateField).isNotEqualTo(from.privateField);
assertThat(to.privateTransientField).isNotEqualTo(from.privateTransientField);
assertThat(to.protectedField).isNotEqualTo(from.protectedField);
// when
tool.copyToMock(from, to);
// then
assertEquals(from.defaultField, to.defaultField);
assertEquals(from.instancePublicField, to.instancePublicField);
assertEquals(from.privateField, to.privateField);
assertEquals(from.privateTransientField, to.privateTransientField);
assertEquals(from.protectedField, to.protectedField);
}
@Test
public void shouldCopyValuesOfInheritedFields() throws Exception {
//given
((InheritMe) from).privateInherited = "foo";
((InheritMe) from).protectedInherited = "bar";
assertThat(((InheritMe) to).privateInherited).isNotEqualTo(((InheritMe) from).privateInherited);
//when
tool.copyToMock(from, to);
//then
assertEquals(((InheritMe) from).privateInherited, ((InheritMe) to).privateInherited);
}
@Test
public void shouldEnableAndThenDisableAccessibility() throws Exception {
//given
Field privateField = SomeObject.class.getDeclaredField("privateField");
assertFalse(privateField.isAccessible());
//when
tool.copyToMock(from, to);
//then
privateField = SomeObject.class.getDeclaredField("privateField");
assertFalse(privateField.isAccessible());
}
@Test
public void shouldContinueEvenIfThereAreProblemsCopyingSingleFieldValue() throws Exception {
//given
tool.fieldCopier = mock(FieldCopier.class);
doNothing().
doThrow(new IllegalAccessException()).
doNothing().
when(tool.fieldCopier).
copyValue(anyObject(), anyObject(), any(Field.class));
//when
tool.copyToMock(from, to);
//then
verify(tool.fieldCopier, atLeast(3)).copyValue(any(), any(), any(Field.class));
}
@Test
public void shouldBeAbleToCopyFromRealObjectToRealObject() throws Exception {
// given
from.defaultField = "defaultField";
from.instancePublicField = new SomeOtherObject();
from.privateField = 1;
from.privateTransientField = 2;
from.protectedField = "protectedField";
from.protectedInherited = "protectedInherited";
to = new SomeObject(0);
// when
tool.copyToRealObject(from, to);
// then
assertEquals(from.defaultField, to.defaultField);
assertEquals(from.instancePublicField, to.instancePublicField);
assertEquals(from.privateField, to.privateField);
assertEquals(from.privateTransientField, to.privateTransientField);
assertEquals(from.protectedField, to.protectedField);
assertEquals(from.protectedInherited, to.protectedInherited);
}
}