Home | History | Annotate | Download | only in basicapi
      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 org.junit.Assert.*;
     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
     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
     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
     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
     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
     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
     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
    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
    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
    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
    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 
    174         public Foo doSomething() {
    175             return foo;
    176         }
    177     }
    178 
    179     class Foo implements Serializable {
    180         Bar bar;
    181         Foo() {
    182             bar = new Bar();
    183             bar.foo = this;
    184         }
    185     }
    186 
    187     @Test
    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
    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
    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
    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
    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;
    268         public Object answer(InvocationOnMock invocation) throws Throwable {
    269             invocation.getArguments();
    270             invocation.getMock();
    271             return string;
    272         }
    273     }
    274 
    275     @Test
    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
    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
    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
    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
    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 {
    352         SerializableAndNoDefaultConstructor(Observable o) { super(); }
    353     }
    354 
    355     @Test
    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 {
    363         private AClassWithPrivateNoArgConstructor() {}
    364         List returningSomething() { return Collections.emptyList(); }
    365     }
    366 
    367     @Test
    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
    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