Home | History | Annotate | Download | only in spies
      1 /*
      2  * Copyright (c) 2007 Mockito contributors
      3  * This program is made available under the terms of the MIT License.
      4  */
      5 
      6 package org.mockitousage.spies;
      7 
      8 import net.bytebuddy.ByteBuddy;
      9 import net.bytebuddy.ClassFileVersion;
     10 import net.bytebuddy.description.modifier.TypeManifestation;
     11 import net.bytebuddy.description.modifier.Visibility;
     12 import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
     13 import net.bytebuddy.implementation.FixedValue;
     14 import org.assertj.core.api.Assertions;
     15 import org.junit.Test;
     16 import org.mockito.exceptions.base.MockitoException;
     17 import org.mockito.invocation.InvocationOnMock;
     18 import org.mockito.stubbing.Answer;
     19 import org.mockitoutil.TestBase;
     20 
     21 import java.util.List;
     22 
     23 import static junit.framework.TestCase.fail;
     24 import static org.junit.Assume.assumeTrue;
     25 import static org.mockito.Mockito.mock;
     26 import static org.mockito.Mockito.spy;
     27 import static org.mockito.Mockito.verify;
     28 import static org.mockito.Mockito.when;
     29 
     30 @SuppressWarnings({"unchecked"})
     31 public class SpyingOnInterfacesTest extends TestBase {
     32 
     33     @Test
     34     public void shouldFailFastWhenCallingRealMethodOnInterface() throws Exception {
     35         List<?> list = mock(List.class);
     36         try {
     37             //when
     38             when(list.get(0)).thenCallRealMethod();
     39             //then
     40             fail();
     41         } catch (MockitoException e) {
     42         }
     43     }
     44 
     45     @Test
     46     public void shouldFailInRuntimeWhenCallingRealMethodOnInterface() throws Exception {
     47         //given
     48         List<Object> list = mock(List.class);
     49         when(list.get(0)).thenAnswer(
     50                 new Answer<Object>() {
     51                     public Object answer(InvocationOnMock invocation) throws Throwable {
     52                         return invocation.callRealMethod();
     53                     }
     54                 }
     55         );
     56         try {
     57             //when
     58             list.get(0);
     59             //then
     60             fail();
     61         } catch (MockitoException e) {
     62         }
     63     }
     64 
     65     @Test
     66     public void shouldAllowDelegatingToDefaultMethod() throws Exception {
     67         assumeTrue("Test can only be executed on Java 8 capable VMs", ClassFileVersion.ofThisVm().isAtLeast(ClassFileVersion.JAVA_V8));
     68 
     69         Class<?> type = new ByteBuddy()
     70                 .makeInterface()
     71                 .defineMethod("foo", String.class, Visibility.PUBLIC)
     72                 .intercept(FixedValue.value("bar"))
     73                 .make()
     74                 .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
     75                 .getLoaded();
     76 
     77         Object object = mock(type);
     78 
     79         //when
     80         when(type.getMethod("foo").invoke(object)).thenCallRealMethod();
     81         //then
     82         Assertions.assertThat(type.getMethod("foo").invoke(object)).isEqualTo((Object) "bar");
     83         type.getMethod("foo").invoke(verify(object));
     84     }
     85 
     86     @Test
     87     public void shouldAllowSpyingOnDefaultMethod() throws Exception {
     88         assumeTrue("Test can only be executed on Java 8 capable VMs", ClassFileVersion.ofThisVm().isAtLeast(ClassFileVersion.JAVA_V8));
     89 
     90         Class<?> iFace = new ByteBuddy()
     91                 .makeInterface()
     92                 .defineMethod("foo", String.class, Visibility.PUBLIC)
     93                 .intercept(FixedValue.value("bar"))
     94                 .make()
     95                 .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
     96                 .getLoaded();
     97 
     98         Class<?> impl = new ByteBuddy()
     99                 .subclass(iFace)
    100                 .make()
    101                 .load(iFace.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
    102                 .getLoaded();
    103 
    104         Object object = spy(impl.newInstance());
    105 
    106         //when
    107         Assertions.assertThat(impl.getMethod("foo").invoke(object)).isEqualTo((Object) "bar");
    108         //then
    109         impl.getMethod("foo").invoke(verify(object));
    110     }
    111 }
    112