• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
shouldFailFastWhenCallingRealMethodOnInterface()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
shouldFailInRuntimeWhenCallingRealMethodOnInterface()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
shouldAllowDelegatingToDefaultMethod()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
shouldAllowSpyingOnDefaultMethod()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