| /* |
| * 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)); |
| } |
| } |