1 /* 2 * Copyright (c) 2017 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockito.internal.creation.bytebuddy; 6 7 import net.bytebuddy.ByteBuddy; 8 import org.junit.Test; 9 import org.mockito.Mockito; 10 import org.mockito.internal.creation.MockSettingsImpl; 11 import org.mockito.internal.handler.MockHandlerImpl; 12 import org.mockito.invocation.InvocationContainer; 13 import org.mockito.internal.stubbing.answers.CallsRealMethods; 14 import org.mockito.invocation.Invocation; 15 import org.mockito.invocation.MockHandler; 16 import org.mockito.mock.MockCreationSettings; 17 import org.mockito.mock.SerializableMode; 18 import org.mockito.plugins.MockMaker; 19 import org.mockito.stubbing.Answer; 20 import org.mockitoutil.ClassLoaders; 21 import org.mockitoutil.SimpleSerializationUtil; 22 import org.objenesis.ObjenesisStd; 23 24 import java.io.Serializable; 25 import java.util.List; 26 27 import static org.assertj.core.api.Assertions.assertThat; 28 import static org.junit.Assert.fail; 29 import static org.mockitoutil.ClassLoaders.coverageTool; 30 31 public abstract class AbstractByteBuddyMockMakerTest<MM extends MockMaker> { 32 33 protected final MM mockMaker; 34 35 public AbstractByteBuddyMockMakerTest(MM mockMaker) { 36 this.mockMaker = mockMaker; 37 } 38 39 protected abstract Class<?> mockTypeOf(Class<?> type); 40 41 @Test 42 public void should_create_mock_from_interface() throws Exception { 43 SomeInterface proxy = mockMaker.createMock(settingsFor(SomeInterface.class), dummyHandler()); 44 45 Class<?> superClass = proxy.getClass().getSuperclass(); 46 assertThat(superClass).isEqualTo(Object.class); 47 } 48 49 50 @Test 51 public void should_create_mock_from_class() throws Exception { 52 ClassWithoutConstructor proxy = mockMaker.createMock(settingsFor(ClassWithoutConstructor.class), dummyHandler()); 53 54 Class<?> superClass = mockTypeOf(proxy.getClass()); 55 assertThat(superClass).isEqualTo(ClassWithoutConstructor.class); 56 } 57 58 @Test 59 public void should_create_mock_from_class_even_when_constructor_is_dodgy() throws Exception { 60 try { 61 new ClassWithDodgyConstructor(); 62 fail(); 63 } catch (Exception expected) {} 64 65 ClassWithDodgyConstructor mock = mockMaker.createMock(settingsFor(ClassWithDodgyConstructor.class), dummyHandler()); 66 assertThat(mock).isNotNull(); 67 } 68 69 @Test 70 public void should_mocks_have_different_interceptors() throws Exception { 71 SomeClass mockOne = mockMaker.createMock(settingsFor(SomeClass.class), dummyHandler()); 72 SomeClass mockTwo = mockMaker.createMock(settingsFor(SomeClass.class), dummyHandler()); 73 74 MockHandler handlerOne = mockMaker.getHandler(mockOne); 75 MockHandler handlerTwo = mockMaker.getHandler(mockTwo); 76 77 78 assertThat(handlerOne).isNotSameAs(handlerTwo); 79 } 80 81 @Test 82 public void should_use_ancillary_Types() { 83 SomeClass mock = mockMaker.createMock(settingsFor(SomeClass.class, SomeInterface.class), dummyHandler()); 84 85 assertThat(mock).isInstanceOf(SomeInterface.class); 86 } 87 88 @Test 89 public void should_create_class_by_constructor() { 90 OtherClass mock = mockMaker.createMock(settingsWithConstructorFor(OtherClass.class), dummyHandler()); 91 assertThat(mock).isNotNull(); 92 } 93 94 @Test 95 public void should_allow_serialization() throws Exception { 96 SerializableClass proxy = mockMaker.createMock(serializableSettingsFor(SerializableClass.class, SerializableMode.BASIC), dummyHandler()); 97 98 SerializableClass serialized = SimpleSerializationUtil.serializeAndBack(proxy); 99 assertThat(serialized).isNotNull(); 100 101 MockHandler handlerOne = mockMaker.getHandler(proxy); 102 MockHandler handlerTwo = mockMaker.getHandler(serialized); 103 104 assertThat(handlerOne).isNotSameAs(handlerTwo); 105 } 106 107 @Test 108 public void should_create_mock_from_class_with_super_call_to_final_method() throws Exception { 109 MockCreationSettings<CallingSuperMethodClass> settings = settingsWithSuperCall(CallingSuperMethodClass.class); 110 SampleClass proxy = mockMaker.createMock(settings, new MockHandlerImpl<CallingSuperMethodClass>(settings)); 111 assertThat(proxy.foo()).isEqualTo("foo"); 112 } 113 114 @Test 115 public void should_reset_mock_and_set_new_handler() throws Throwable { 116 MockCreationSettings<SampleClass> settings = settingsWithSuperCall(SampleClass.class); 117 SampleClass proxy = mockMaker.createMock(settings, new MockHandlerImpl<SampleClass>(settings)); 118 119 MockHandler handler = new MockHandlerImpl<SampleClass>(settings); 120 mockMaker.resetMock(proxy, handler, settings); 121 assertThat(mockMaker.getHandler(proxy)).isSameAs(handler); 122 } 123 124 class SomeClass {} 125 interface SomeInterface {} 126 static class OtherClass {} 127 static class SerializableClass implements Serializable {} 128 129 private class ClassWithoutConstructor {} 130 131 private class ClassWithDodgyConstructor { 132 public ClassWithDodgyConstructor() { 133 throw new RuntimeException(); 134 } 135 } 136 137 @Test 138 public void instantiate_fine_when_objenesis_on_the_classpath() throws Exception { 139 // given 140 ClassLoader classpath_with_objenesis = ClassLoaders.excludingClassLoader() 141 .withCodeSourceUrlOf(Mockito.class, ByteBuddy.class, ObjenesisStd.class) 142 .withCodeSourceUrlOf(coverageTool()) 143 .build(); 144 145 Class<?> mock_maker_class_loaded_fine_until = Class.forName( 146 "org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker", 147 true, 148 classpath_with_objenesis 149 ); 150 151 // when 152 mock_maker_class_loaded_fine_until.newInstance(); 153 154 // then everything went fine 155 } 156 157 private static <T> MockCreationSettings<T> settingsFor(Class<T> type, Class<?>... extraInterfaces) { 158 MockSettingsImpl<T> mockSettings = new MockSettingsImpl<T>(); 159 mockSettings.setTypeToMock(type); 160 if(extraInterfaces.length > 0) mockSettings.extraInterfaces(extraInterfaces); 161 return mockSettings; 162 } 163 164 private static <T> MockCreationSettings<T> serializableSettingsFor(Class<T> type, SerializableMode serializableMode) { 165 MockSettingsImpl<T> mockSettings = new MockSettingsImpl<T>(); 166 mockSettings.serializable(serializableMode); 167 mockSettings.setTypeToMock(type); 168 return mockSettings; 169 } 170 171 private static <T> MockCreationSettings<T> settingsWithConstructorFor(Class<T> type) { 172 MockSettingsImpl<T> mockSettings = new MockSettingsImpl<T>(); 173 mockSettings.setTypeToMock(type); 174 return mockSettings; 175 } 176 177 private static <T> MockCreationSettings<T> settingsWithSuperCall(Class<T> type) { 178 MockSettingsImpl<T> mockSettings = new MockSettingsImpl<T>(); 179 mockSettings.setTypeToMock(type); 180 mockSettings.defaultAnswer(new CallsRealMethods()); 181 return mockSettings; 182 } 183 184 protected static MockHandler dummyHandler() { 185 return new DummyMockHandler(); 186 } 187 188 private static class DummyMockHandler implements MockHandler<Object> { 189 public Object handle(Invocation invocation) throws Throwable { return null; } 190 public MockCreationSettings<Object> getMockSettings() { return null; } 191 public InvocationContainer getInvocationContainer() { return null; } 192 public void setAnswersForStubbing(List<Answer<?>> list) { } 193 } 194 195 private static class SampleClass { 196 public String foo() { 197 return "foo"; 198 } 199 } 200 201 private static class CallingSuperMethodClass extends SampleClass { 202 @Override 203 public String foo() { 204 return super.foo(); 205 } 206 } 207 } 208