• 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 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