1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockito.internal.util; 6 7 import org.mockito.Mockito; 8 import org.mockito.exceptions.misusing.NotAMockException; 9 import org.mockito.internal.configuration.plugins.Plugins; 10 import org.mockito.internal.creation.settings.CreationSettings; 11 import org.mockito.internal.stubbing.InvocationContainerImpl; 12 import org.mockito.internal.util.reflection.LenientCopyTool; 13 import org.mockito.invocation.MockHandler; 14 import org.mockito.mock.MockCreationSettings; 15 import org.mockito.mock.MockName; 16 import org.mockito.plugins.MockMaker; 17 import org.mockito.plugins.MockMaker.TypeMockability; 18 19 import static org.mockito.internal.handler.MockHandlerFactory.createMockHandler; 20 21 @SuppressWarnings("unchecked") 22 public class MockUtil { 23 24 private static final MockMaker mockMaker = Plugins.getMockMaker(); 25 MockUtil()26 private MockUtil() {} 27 typeMockabilityOf(Class<?> type)28 public static TypeMockability typeMockabilityOf(Class<?> type) { 29 return mockMaker.isTypeMockable(type); 30 } 31 createMock(MockCreationSettings<T> settings)32 public static <T> T createMock(MockCreationSettings<T> settings) { 33 MockHandler mockHandler = createMockHandler(settings); 34 35 T mock = mockMaker.createMock(settings, mockHandler); 36 37 Object spiedInstance = settings.getSpiedInstance(); 38 if (spiedInstance != null) { 39 new LenientCopyTool().copyToMock(spiedInstance, mock); 40 } 41 42 return mock; 43 } 44 resetMock(T mock)45 public static <T> void resetMock(T mock) { 46 MockHandler oldHandler = getMockHandler(mock); 47 MockCreationSettings settings = oldHandler.getMockSettings(); 48 MockHandler newHandler = createMockHandler(settings); 49 50 mockMaker.resetMock(mock, newHandler, settings); 51 } 52 getMockHandler(T mock)53 public static <T> MockHandler<T> getMockHandler(T mock) { 54 if (mock == null) { 55 throw new NotAMockException("Argument should be a mock, but is null!"); 56 } 57 58 if (isMock(mock)) { 59 return mockMaker.getHandler(mock); 60 } else { 61 throw new NotAMockException("Argument should be a mock, but is: " + mock.getClass()); 62 } 63 } 64 getInvocationContainer(Object mock)65 public static InvocationContainerImpl getInvocationContainer(Object mock) { 66 return (InvocationContainerImpl) getMockHandler(mock).getInvocationContainer(); 67 } 68 isSpy(Object mock)69 public static boolean isSpy(Object mock) { 70 return isMock(mock) && getMockSettings(mock).getDefaultAnswer() == Mockito.CALLS_REAL_METHODS; 71 } 72 isMock(Object mock)73 public static boolean isMock(Object mock) { 74 // TODO SF (perf tweak) in our codebase we call mockMaker.getHandler() multiple times unnecessarily 75 // This is not ideal because getHandler() can be expensive (reflective calls inside mock maker) 76 // The frequent pattern in the codebase are separate calls to: 1) isMock(mock) then 2) getMockHandler(mock) 77 // We could replace it with using mockingDetails().isMock() 78 // Let's refactor the codebase and use new mockingDetails() in all relevant places. 79 // Potentially we could also move other methods to MockitoMock, some other candidates: getInvocationContainer, isSpy, etc. 80 // This also allows us to reuse our public API MockingDetails 81 return mock != null && mockMaker.getHandler(mock) != null; 82 } 83 getMockName(Object mock)84 public static MockName getMockName(Object mock) { 85 return getMockHandler(mock).getMockSettings().getMockName(); 86 } 87 maybeRedefineMockName(Object mock, String newName)88 public static void maybeRedefineMockName(Object mock, String newName) { 89 MockName mockName = getMockName(mock); 90 //TODO SF hacky... 91 MockCreationSettings mockSettings = getMockHandler(mock).getMockSettings(); 92 if (mockName.isDefault() && mockSettings instanceof CreationSettings) { 93 ((CreationSettings) mockSettings).setMockName(new MockNameImpl(newName)); 94 } 95 } 96 getMockSettings(Object mock)97 public static MockCreationSettings getMockSettings(Object mock) { 98 return getMockHandler(mock).getMockSettings(); 99 } 100 } 101