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 org.assertj.core.api.Assertions; 9 import org.junit.Test; 10 import org.mockito.InOrder; 11 import org.mockito.Mockito; 12 import org.mockito.internal.matchers.Any; 13 import org.mockito.internal.stubbing.answers.ThrowsException; 14 import org.mockito.invocation.InvocationOnMock; 15 import org.mockito.stubbing.Answer; 16 import org.mockitousage.IMethods; 17 import org.mockitoutil.SimpleSerializationUtil; 18 import org.mockitoutil.TestBase; 19 20 import java.io.ByteArrayOutputStream; 21 import java.io.ObjectStreamException; 22 import java.io.Serializable; 23 import java.util.ArrayList; 24 import java.util.Collections; 25 import java.util.List; 26 import java.util.Observable; 27 28 import static junit.framework.TestCase.*; 29 import static org.junit.Assume.assumeFalse; 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 List<Object> list = new ArrayList<Object>(); 279 List<Object> spy = mock(ArrayList.class, withSettings() 280 .spiedInstance(list) 281 .defaultAnswer(CALLS_REAL_METHODS) 282 .serializable()); 283 when(spy.size()).thenReturn(100); 284 285 // when 286 ByteArrayOutputStream serialized = serializeMock(spy); 287 288 // then 289 List<?> readObject = deserializeMock(serialized, List.class); 290 assertEquals(100, readObject.size()); 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 350 351 static class SerializableAndNoDefaultConstructor implements Serializable { SerializableAndNoDefaultConstructor(Observable o)352 SerializableAndNoDefaultConstructor(Observable o) { super(); } 353 } 354 355 @Test should_be_able_to_serialize_type_that_implements_Serializable_but_but_dont_declare_a_no_arg_constructor()356 public void should_be_able_to_serialize_type_that_implements_Serializable_but_but_dont_declare_a_no_arg_constructor() throws Exception { 357 serializeAndBack(mock(SerializableAndNoDefaultConstructor.class)); 358 } 359 360 361 362 public static class AClassWithPrivateNoArgConstructor { AClassWithPrivateNoArgConstructor()363 private AClassWithPrivateNoArgConstructor() {} returningSomething()364 List returningSomething() { return Collections.emptyList(); } 365 } 366 367 @Test private_constructor_currently_not_supported_at_the_moment_at_deserialization_time()368 public void private_constructor_currently_not_supported_at_the_moment_at_deserialization_time() throws Exception { 369 // given 370 AClassWithPrivateNoArgConstructor mockWithPrivateConstructor = Mockito.mock( 371 AClassWithPrivateNoArgConstructor.class, 372 Mockito.withSettings().serializable() 373 ); 374 375 try { 376 // when 377 SimpleSerializationUtil.serializeAndBack(mockWithPrivateConstructor); 378 fail("should have thrown an ObjectStreamException or a subclass of it"); 379 } catch (ObjectStreamException e) { 380 // then 381 Assertions.assertThat(e.toString()).contains("no valid constructor"); 382 } 383 } 384 385 386 @Test BUG_ISSUE_399_try_some_mocks_with_current_answers()387 public void BUG_ISSUE_399_try_some_mocks_with_current_answers() throws Exception { 388 assumeFalse(System.getProperty("java.version").startsWith("1.6")); // Bug in last public HotSpot 1.6 389 390 IMethods iMethods = mock(IMethods.class, withSettings().serializable().defaultAnswer(RETURNS_DEEP_STUBS)); 391 392 when(iMethods.iMethodsReturningMethod().linkedListReturningMethod().contains(anyString())).thenReturn(false); 393 394 serializeAndBack(iMethods); 395 } 396 } 397