• 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.serialization;
6 
7 import static org.assertj.core.api.Assertions.assertThat;
8 
9 import java.io.ByteArrayInputStream;
10 import java.util.Collections;
11 import java.util.List;
12 import java.util.concurrent.Callable;
13 
14 import net.bytebuddy.ClassFileVersion;
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.mockito.Mockito;
18 import org.mockito.mock.SerializableMode;
19 import org.mockitousage.IMethods;
20 import org.mockitoutil.SimplePerRealmReloadingClassLoader;
21 import org.mockitoutil.SimpleSerializationUtil;
22 
23 public class AcrossClassLoaderSerializationTest {
24 
25     public IMethods mock;
26 
27     @Before
reproduce_CCE_by_creating_a_mock_with_IMethods_before()28     public void reproduce_CCE_by_creating_a_mock_with_IMethods_before() throws Exception {
29         mock = Mockito.mock(IMethods.class);
30     }
31 
32     @Test
check_that_mock_can_be_serialized_in_a_classloader_and_deserialized_in_another()33     public void check_that_mock_can_be_serialized_in_a_classloader_and_deserialized_in_another()
34             throws Exception {
35         // No longer supported starting with JDK 16+
36         if (!ClassFileVersion.ofThisVm().isAtMost(ClassFileVersion.JAVA_V16)) {
37             return;
38         }
39         byte[] bytes = create_mock_and_serialize_it_in_class_loader_A();
40 
41         Object the_deserialized_mock = read_stream_and_deserialize_it_in_class_loader_B(bytes);
42         assertThat(the_deserialized_mock.getClass().getName())
43                 .startsWith("org.mockito.codegen.AClassToBeMockedInThisTestOnlyAndInCallablesOnly");
44     }
45 
read_stream_and_deserialize_it_in_class_loader_B(byte[] bytes)46     private Object read_stream_and_deserialize_it_in_class_loader_B(byte[] bytes) throws Exception {
47         return new SimplePerRealmReloadingClassLoader(
48                         this.getClass().getClassLoader(), isolating_test_classes())
49                 .doInRealm(
50                         "org.mockitousage.serialization.AcrossClassLoaderSerializationTest$ReadStreamAndDeserializeIt",
51                         new Class<?>[] {byte[].class},
52                         new Object[] {bytes});
53     }
54 
create_mock_and_serialize_it_in_class_loader_A()55     private byte[] create_mock_and_serialize_it_in_class_loader_A() throws Exception {
56         return (byte[])
57                 new SimplePerRealmReloadingClassLoader(
58                                 this.getClass().getClassLoader(), isolating_test_classes())
59                         .doInRealm(
60                                 "org.mockitousage.serialization.AcrossClassLoaderSerializationTest$CreateMockAndSerializeIt");
61     }
62 
isolating_test_classes()63     private SimplePerRealmReloadingClassLoader.ReloadClassPredicate isolating_test_classes() {
64         return new SimplePerRealmReloadingClassLoader.ReloadClassPredicate() {
65             public boolean acceptReloadOf(String qualifiedName) {
66                 return qualifiedName.contains("org.mockitousage")
67                         || qualifiedName.contains("org.mockitoutil");
68             }
69         };
70     }
71 
72     // see create_mock_and_serialize_it_in_class_loader_A
73     public static class CreateMockAndSerializeIt implements Callable<byte[]> {
74         public byte[] call() throws Exception {
75             AClassToBeMockedInThisTestOnlyAndInCallablesOnly mock =
76                     Mockito.mock(
77                             AClassToBeMockedInThisTestOnlyAndInCallablesOnly.class,
78                             Mockito.withSettings()
79                                     .serializable(SerializableMode.ACROSS_CLASSLOADERS));
80             // use MethodProxy before
81             mock.returningSomething();
82 
83             return SimpleSerializationUtil.serializeMock(mock).toByteArray();
84         }
85     }
86 
87     // see read_stream_and_deserialize_it_in_class_loader_B
88     public static class ReadStreamAndDeserializeIt implements Callable<Object> {
89         private byte[] bytes;
90 
91         public ReadStreamAndDeserializeIt(byte[] bytes) {
92             this.bytes = bytes;
93         }
94 
95         public Object call() throws Exception {
96             ByteArrayInputStream to_unserialize = new ByteArrayInputStream(bytes);
97             return SimpleSerializationUtil.deserializeMock(
98                     to_unserialize, AClassToBeMockedInThisTestOnlyAndInCallablesOnly.class);
99         }
100     }
101 
102     public static class AClassToBeMockedInThisTestOnlyAndInCallablesOnly {
103         List returningSomething() {
104             return Collections.emptyList();
105         }
106     }
107 }
108