blob: d9fb5392a2cd044671f63bb332c1c56d6a2dc238 [file] [log] [blame]
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockitousage.spies;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.description.modifier.TypeManifestation;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.FixedValue;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.mockitoutil.TestBase;
import java.util.List;
import static junit.framework.TestCase.fail;
import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@SuppressWarnings({"unchecked"})
public class SpyingOnInterfacesTest extends TestBase {
@Test
public void shouldFailFastWhenCallingRealMethodOnInterface() throws Exception {
List<?> list = mock(List.class);
try {
//when
when(list.get(0)).thenCallRealMethod();
//then
fail();
} catch (MockitoException e) {
}
}
@Test
public void shouldFailInRuntimeWhenCallingRealMethodOnInterface() throws Exception {
//given
List<Object> list = mock(List.class);
when(list.get(0)).thenAnswer(
new Answer<Object>() {
public Object answer(InvocationOnMock invocation) throws Throwable {
return invocation.callRealMethod();
}
}
);
try {
//when
list.get(0);
//then
fail();
} catch (MockitoException e) {
}
}
@Test
public void shouldAllowDelegatingToDefaultMethod() throws Exception {
assumeTrue("Test can only be executed on Java 8 capable VMs", ClassFileVersion.ofThisVm().isAtLeast(ClassFileVersion.JAVA_V8));
Class<?> type = new ByteBuddy()
.makeInterface()
.defineMethod("foo", String.class, Visibility.PUBLIC)
.intercept(FixedValue.value("bar"))
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
Object object = mock(type);
//when
when(type.getMethod("foo").invoke(object)).thenCallRealMethod();
//then
Assertions.assertThat(type.getMethod("foo").invoke(object)).isEqualTo((Object) "bar");
type.getMethod("foo").invoke(verify(object));
}
@Test
public void shouldAllowSpyingOnDefaultMethod() throws Exception {
assumeTrue("Test can only be executed on Java 8 capable VMs", ClassFileVersion.ofThisVm().isAtLeast(ClassFileVersion.JAVA_V8));
Class<?> iFace = new ByteBuddy()
.makeInterface()
.defineMethod("foo", String.class, Visibility.PUBLIC)
.intercept(FixedValue.value("bar"))
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
Class<?> impl = new ByteBuddy()
.subclass(iFace)
.make()
.load(iFace.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
Object object = spy(impl.newInstance());
//when
Assertions.assertThat(impl.getMethod("foo").invoke(object)).isEqualTo((Object) "bar");
//then
impl.getMethod("foo").invoke(verify(object));
}
}