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