1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dx.mockito.inline; 18 19 import android.util.Log; 20 21 import org.mockito.invocation.MockHandler; 22 import org.mockito.mock.MockCreationSettings; 23 import org.mockito.plugins.InlineMockMaker; 24 import org.mockito.plugins.MockMaker; 25 26 import java.lang.reflect.InvocationTargetException; 27 import java.util.ArrayList; 28 29 /** 30 * Multiplexes multiple mock makers 31 */ 32 public final class MockMakerMultiplexer implements InlineMockMaker { 33 private static final String LOG_TAG = MockMakerMultiplexer.class.getSimpleName(); 34 private final static MockMaker[] MOCK_MAKERS; 35 36 static { 37 String[] potentialMockMakers = new String[] { 38 "com.android.dx.mockito.inline.InlineStaticMockMaker", 39 InlineDexmakerMockMaker.class.getName() 40 }; 41 42 ArrayList<MockMaker> mockMakers = new ArrayList<>(); 43 for (String potentialMockMaker : potentialMockMakers) { 44 try { 45 Class<? extends MockMaker> mockMakerClass = (Class<? extends MockMaker>) 46 Class.forName(potentialMockMaker); 47 mockMakers.add(mockMakerClass.getDeclaredConstructor().newInstance()); 48 } catch (ClassNotFoundException | InstantiationException | IllegalAccessException 49 | NoSuchMethodException | InvocationTargetException e) { 50 if (potentialMockMaker.equals(InlineDexmakerMockMaker.class.getName())) { 51 Log.e(LOG_TAG, "Could not init mockmaker " + potentialMockMaker, e); 52 } else { 53 // Additional mock makers might not be loaded 54 Log.e(LOG_TAG, "Could not init mockmaker " + potentialMockMaker); 55 } 56 } 57 } 58 59 MOCK_MAKERS = mockMakers.toArray(new MockMaker[]{}); 60 } 61 62 @Override createMock(MockCreationSettings<T> settings, MockHandler handler)63 public <T> T createMock(MockCreationSettings<T> settings, MockHandler handler) { 64 for (MockMaker mockMaker : MOCK_MAKERS) { 65 T mock = mockMaker.createMock(settings, handler); 66 67 if (mock != null) { 68 return mock; 69 } 70 } 71 72 return null; 73 } 74 75 @Override getHandler(Object mock)76 public MockHandler getHandler(Object mock) { 77 for (MockMaker mockMaker : MOCK_MAKERS) { 78 MockHandler handler = mockMaker.getHandler(mock); 79 80 if (handler != null) { 81 return handler; 82 } 83 } 84 85 return null; 86 } 87 88 @Override resetMock(Object mock, MockHandler newHandler, MockCreationSettings settings)89 public void resetMock(Object mock, MockHandler newHandler, MockCreationSettings settings) { 90 for (MockMaker mockMaker : MOCK_MAKERS) { 91 mockMaker.resetMock(mock, newHandler, settings); 92 } 93 } 94 95 @Override isTypeMockable(Class<?> type)96 public TypeMockability isTypeMockable(Class<?> type) { 97 for (MockMaker mockMaker : MOCK_MAKERS) { 98 TypeMockability mockability = mockMaker.isTypeMockable(type); 99 100 if (mockability != null) { 101 return mockability; 102 } 103 } 104 105 return null; 106 } 107 108 @Override clearMock(Object mock)109 public void clearMock(Object mock) { 110 for (MockMaker mockMaker : MOCK_MAKERS) { 111 if (!(mockMaker instanceof InlineMockMaker)) { 112 continue; 113 } 114 115 InlineMockMaker inlineMockMaker = (InlineMockMaker) mockMaker; 116 inlineMockMaker.clearMock(mock); 117 } 118 } 119 120 @Override clearAllMocks()121 public void clearAllMocks() { 122 for (MockMaker mockMaker : MOCK_MAKERS) { 123 if (!(mockMaker instanceof InlineMockMaker)) { 124 continue; 125 } 126 127 InlineMockMaker inlineMockMaker = (InlineMockMaker) mockMaker; 128 inlineMockMaker.clearAllMocks(); 129 } 130 } 131 } 132