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.basicapi; 7 8 import net.bytebuddy.ClassFileVersion; 9 import org.assertj.core.api.Assertions; 10 import org.junit.Test; 11 import org.mockito.InOrder; 12 import org.mockito.Mockito; 13 import org.mockito.internal.matchers.Any; 14 import org.mockito.internal.stubbing.answers.ThrowsException; 15 import org.mockito.invocation.InvocationOnMock; 16 import org.mockito.stubbing.Answer; 17 import org.mockitousage.IMethods; 18 import org.mockitoutil.SimpleSerializationUtil; 19 import org.mockitoutil.TestBase; 20 21 import java.io.ByteArrayOutputStream; 22 import java.io.ObjectStreamException; 23 import java.io.Serializable; 24 import java.util.Collections; 25 import java.util.List; 26 import java.util.Observable; 27 28 import static org.junit.Assert.*; 29 import static org.junit.Assume.assumeTrue; 30 import static org.mockito.Mockito.*; 31 import static org.mockitoutil.SimpleSerializationUtil.*; 32 33 @SuppressWarnings({"unchecked", "serial"}) 34 public class MocksSerializationTest extends TestBase implements Serializable { 35 36 private static final long serialVersionUID = 6160482220413048624L; 37 38 @Test should_allow_throws_exception_to_be_serializable()39 public void should_allow_throws_exception_to_be_serializable() throws Exception { 40 // given 41 Bar mock = mock(Bar.class, new ThrowsException(new RuntimeException())); 42 // when-serialize then-deserialize 43 serializeAndBack(mock); 44 } 45 46 @Test should_allow_method_delegation()47 public void should_allow_method_delegation() throws Exception { 48 // given 49 Bar barMock = mock(Bar.class, withSettings().serializable()); 50 Foo fooMock = mock(Foo.class); 51 when(barMock.doSomething()).thenAnswer(new ThrowsException(new RuntimeException())); 52 53 //when-serialize then-deserialize 54 serializeAndBack(barMock); 55 } 56 57 @Test should_allow_mock_to_be_serializable()58 public void should_allow_mock_to_be_serializable() throws Exception { 59 // given 60 IMethods mock = mock(IMethods.class, withSettings().serializable()); 61 62 // when-serialize then-deserialize 63 serializeAndBack(mock); 64 } 65 66 @Test should_allow_mock_and_boolean_value_to_serializable()67 public void should_allow_mock_and_boolean_value_to_serializable() throws Exception { 68 // given 69 IMethods mock = mock(IMethods.class, withSettings().serializable()); 70 when(mock.booleanReturningMethod()).thenReturn(true); 71 72 // when 73 ByteArrayOutputStream serialized = serializeMock(mock); 74 75 // then 76 IMethods readObject = deserializeMock(serialized, IMethods.class); 77 assertTrue(readObject.booleanReturningMethod()); 78 } 79 80 @Test should_allow_mock_and_string_value_to_be_serializable()81 public void should_allow_mock_and_string_value_to_be_serializable() throws Exception { 82 // given 83 IMethods mock = mock(IMethods.class, withSettings().serializable()); 84 String value = "value"; 85 when(mock.stringReturningMethod()).thenReturn(value); 86 87 // when 88 ByteArrayOutputStream serialized = serializeMock(mock); 89 90 // then 91 IMethods readObject = deserializeMock(serialized, IMethods.class); 92 assertEquals(value, readObject.stringReturningMethod()); 93 } 94 95 @Test should_all_mock_and_serializable_value_to_be_serialized()96 public void should_all_mock_and_serializable_value_to_be_serialized() throws Exception { 97 // given 98 IMethods mock = mock(IMethods.class, withSettings().serializable()); 99 List<?> value = Collections.emptyList(); 100 when(mock.objectReturningMethodNoArgs()).thenReturn(value); 101 102 // when 103 ByteArrayOutputStream serialized = serializeMock(mock); 104 105 // then 106 IMethods readObject = deserializeMock(serialized, IMethods.class); 107 assertEquals(value, readObject.objectReturningMethodNoArgs()); 108 } 109 110 @Test should_serialize_method_call_with_parameters_that_are_serializable()111 public void should_serialize_method_call_with_parameters_that_are_serializable() throws Exception { 112 IMethods mock = mock(IMethods.class, withSettings().serializable()); 113 List<?> value = Collections.emptyList(); 114 when(mock.objectArgMethod(value)).thenReturn(value); 115 116 // when 117 ByteArrayOutputStream serialized = serializeMock(mock); 118 119 // then 120 IMethods readObject = deserializeMock(serialized, IMethods.class); 121 assertEquals(value, readObject.objectArgMethod(value)); 122 } 123 124 @Test should_serialize_method_calls_using_any_string_matcher()125 public void should_serialize_method_calls_using_any_string_matcher() throws Exception { 126 IMethods mock = mock(IMethods.class, withSettings().serializable()); 127 List<?> value = Collections.emptyList(); 128 when(mock.objectArgMethod(anyString())).thenReturn(value); 129 130 // when 131 ByteArrayOutputStream serialized = serializeMock(mock); 132 133 // then 134 IMethods readObject = deserializeMock(serialized, IMethods.class); 135 assertEquals(value, readObject.objectArgMethod("")); 136 } 137 138 @Test should_verify_called_n_times_for_serialized_mock()139 public void should_verify_called_n_times_for_serialized_mock() throws Exception { 140 IMethods mock = mock(IMethods.class, withSettings().serializable()); 141 List<?> value = Collections.emptyList(); 142 when(mock.objectArgMethod(anyString())).thenReturn(value); 143 mock.objectArgMethod(""); 144 145 // when 146 ByteArrayOutputStream serialized = serializeMock(mock); 147 148 // then 149 IMethods readObject = deserializeMock(serialized, IMethods.class); 150 verify(readObject, times(1)).objectArgMethod(""); 151 } 152 153 @Test should_verify_even_if_some_methods_called_after_serialization()154 public void should_verify_even_if_some_methods_called_after_serialization() throws Exception { 155 //given 156 IMethods mock = mock(IMethods.class, withSettings().serializable()); 157 158 // when 159 mock.simpleMethod(1); 160 ByteArrayOutputStream serialized = serializeMock(mock); 161 IMethods readObject = deserializeMock(serialized, IMethods.class); 162 readObject.simpleMethod(1); 163 164 // then 165 verify(readObject, times(2)).simpleMethod(1); 166 167 //this test is working because it seems that java serialization mechanism replaces all instances 168 //of serialized object in the object graph (if there are any) 169 } 170 171 class Bar implements Serializable { 172 Foo foo; 173 doSomething()174 public Foo doSomething() { 175 return foo; 176 } 177 } 178 179 class Foo implements Serializable { 180 Bar bar; Foo()181 Foo() { 182 bar = new Bar(); 183 bar.foo = this; 184 } 185 } 186 187 @Test should_serialization_work()188 public void should_serialization_work() throws Exception { 189 //given 190 Foo foo = new Foo(); 191 //when 192 foo = serializeAndBack(foo); 193 //then 194 assertSame(foo, foo.bar.foo); 195 } 196 197 @Test should_stub_even_if_some_methods_called_after_serialization()198 public void should_stub_even_if_some_methods_called_after_serialization() throws Exception { 199 //given 200 IMethods mock = mock(IMethods.class, withSettings().serializable()); 201 202 // when 203 when(mock.simpleMethod(1)).thenReturn("foo"); 204 ByteArrayOutputStream serialized = serializeMock(mock); 205 IMethods readObject = deserializeMock(serialized, IMethods.class); 206 when(readObject.simpleMethod(2)).thenReturn("bar"); 207 208 // then 209 assertEquals("foo", readObject.simpleMethod(1)); 210 assertEquals("bar", readObject.simpleMethod(2)); 211 } 212 213 @Test should_verify_call_order_for_serialized_mock()214 public void should_verify_call_order_for_serialized_mock() throws Exception { 215 IMethods mock = mock(IMethods.class, withSettings().serializable()); 216 IMethods mock2 = mock(IMethods.class, withSettings().serializable()); 217 mock.arrayReturningMethod(); 218 mock2.arrayReturningMethod(); 219 220 // when 221 ByteArrayOutputStream serialized = serializeMock(mock); 222 ByteArrayOutputStream serialized2 = serializeMock(mock2); 223 224 // then 225 IMethods readObject = deserializeMock(serialized, IMethods.class); 226 IMethods readObject2 = deserializeMock(serialized2, IMethods.class); 227 InOrder inOrder = inOrder(readObject, readObject2); 228 inOrder.verify(readObject).arrayReturningMethod(); 229 inOrder.verify(readObject2).arrayReturningMethod(); 230 } 231 232 @Test should_remember_interactions_for_serialized_mock()233 public void should_remember_interactions_for_serialized_mock() throws Exception { 234 IMethods mock = mock(IMethods.class, withSettings().serializable()); 235 List<?> value = Collections.emptyList(); 236 when(mock.objectArgMethod(anyString())).thenReturn(value); 237 mock.objectArgMethod("happened"); 238 239 // when 240 ByteArrayOutputStream serialized = serializeMock(mock); 241 242 // then 243 IMethods readObject = deserializeMock(serialized, IMethods.class); 244 verify(readObject, never()).objectArgMethod("never happened"); 245 } 246 247 @Test should_serialize_with_stubbing_callback()248 public void should_serialize_with_stubbing_callback() throws Exception { 249 250 // given 251 IMethods mock = mock(IMethods.class, withSettings().serializable()); 252 CustomAnswersMustImplementSerializableForSerializationToWork answer = 253 new CustomAnswersMustImplementSerializableForSerializationToWork(); 254 answer.string = "return value"; 255 when(mock.objectArgMethod(anyString())).thenAnswer(answer); 256 257 // when 258 ByteArrayOutputStream serialized = serializeMock(mock); 259 260 // then 261 IMethods readObject = deserializeMock(serialized, IMethods.class); 262 assertEquals(answer.string, readObject.objectArgMethod("")); 263 } 264 265 class CustomAnswersMustImplementSerializableForSerializationToWork 266 implements Answer<Object>, Serializable { 267 private String string; answer(InvocationOnMock invocation)268 public Object answer(InvocationOnMock invocation) throws Throwable { 269 invocation.getArguments(); 270 invocation.getMock(); 271 return string; 272 } 273 } 274 275 @Test should_serialize_with_real_object_spy()276 public void should_serialize_with_real_object_spy() throws Exception { 277 // given 278 SerializableClass sample = new SerializableClass(); 279 SerializableClass spy = mock(SerializableClass.class, withSettings() 280 .spiedInstance(sample) 281 .defaultAnswer(CALLS_REAL_METHODS) 282 .serializable()); 283 when(spy.foo()).thenReturn("foo"); 284 285 // when 286 ByteArrayOutputStream serialized = serializeMock(spy); 287 288 // then 289 SerializableClass readObject = deserializeMock(serialized, SerializableClass.class); 290 assertEquals("foo", readObject.foo()); 291 } 292 293 @Test should_serialize_object_mock()294 public void should_serialize_object_mock() throws Exception { 295 // given 296 Any mock = mock(Any.class); 297 298 // when 299 ByteArrayOutputStream serialized = serializeMock(mock); 300 301 // then 302 deserializeMock(serialized, Any.class); 303 } 304 305 @Test should_serialize_real_partial_mock()306 public void should_serialize_real_partial_mock() throws Exception { 307 // given 308 Any mock = mock(Any.class, withSettings().serializable()); 309 when(mock.matches(anyObject())).thenCallRealMethod(); 310 311 // when 312 ByteArrayOutputStream serialized = serializeMock(mock); 313 314 // then 315 Any readObject = deserializeMock(serialized, Any.class); 316 readObject.matches(""); 317 } 318 319 class AlreadySerializable implements Serializable {} 320 321 @Test should_serialize_already_serializable_class()322 public void should_serialize_already_serializable_class() throws Exception { 323 // given 324 AlreadySerializable mock = mock(AlreadySerializable.class, withSettings().serializable()); 325 when(mock.toString()).thenReturn("foo"); 326 327 // when 328 mock = serializeAndBack(mock); 329 330 // then 331 assertEquals("foo", mock.toString()); 332 } 333 334 @Test should_be_serialize_and_have_extra_interfaces()335 public void should_be_serialize_and_have_extra_interfaces() throws Exception { 336 //when 337 IMethods mock = mock(IMethods.class, withSettings().serializable().extraInterfaces(List.class)); 338 IMethods mockTwo = mock(IMethods.class, withSettings().extraInterfaces(List.class).serializable()); 339 340 //then 341 Assertions.assertThat((Object) serializeAndBack((List) mock)) 342 .isInstanceOf(List.class) 343 .isInstanceOf(IMethods.class); 344 Assertions.assertThat((Object) serializeAndBack((List) mockTwo)) 345 .isInstanceOf(List.class) 346 .isInstanceOf(IMethods.class); 347 } 348 349 static class SerializableAndNoDefaultConstructor implements Serializable { SerializableAndNoDefaultConstructor(Observable o)350 SerializableAndNoDefaultConstructor(Observable o) { super(); } 351 } 352 353 @Test should_be_able_to_serialize_type_that_implements_Serializable_but_but_dont_declare_a_no_arg_constructor()354 public void should_be_able_to_serialize_type_that_implements_Serializable_but_but_dont_declare_a_no_arg_constructor() throws Exception { 355 serializeAndBack(mock(SerializableAndNoDefaultConstructor.class)); 356 } 357 358 359 360 public static class AClassWithPrivateNoArgConstructor { AClassWithPrivateNoArgConstructor()361 private AClassWithPrivateNoArgConstructor() {} returningSomething()362 List returningSomething() { return Collections.emptyList(); } 363 } 364 365 @Test private_constructor_currently_not_supported_at_the_moment_at_deserialization_time()366 public void private_constructor_currently_not_supported_at_the_moment_at_deserialization_time() throws Exception { 367 // given 368 AClassWithPrivateNoArgConstructor mockWithPrivateConstructor = Mockito.mock( 369 AClassWithPrivateNoArgConstructor.class, 370 Mockito.withSettings().serializable() 371 ); 372 373 try { 374 // when 375 SimpleSerializationUtil.serializeAndBack(mockWithPrivateConstructor); 376 fail("should have thrown an ObjectStreamException or a subclass of it"); 377 } catch (ObjectStreamException e) { 378 // then 379 Assertions.assertThat(e.toString()).contains("no valid constructor"); 380 } 381 } 382 383 384 @Test BUG_ISSUE_399_try_some_mocks_with_current_answers()385 public void BUG_ISSUE_399_try_some_mocks_with_current_answers() throws Exception { 386 assumeTrue(ClassFileVersion.ofThisVm().isAtLeast(ClassFileVersion.JAVA_V7)); 387 388 IMethods iMethods = mock(IMethods.class, withSettings().serializable().defaultAnswer(RETURNS_DEEP_STUBS)); 389 390 when(iMethods.iMethodsReturningMethod().linkedListReturningMethod().contains(anyString())).thenReturn(false); 391 392 serializeAndBack(iMethods); 393 } 394 395 public static class SerializableClass implements Serializable { 396 foo()397 public String foo() { 398 return null; 399 } 400 } 401 } 402