MockUtil.java revision e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7
1/*
2 * Copyright (c) 2007 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5package org.mockito.internal.util;
6
7import org.mockito.exceptions.misusing.NotAMockException;
8import org.mockito.internal.InternalMockHandler;
9import org.mockito.internal.configuration.ClassPathLoader;
10import org.mockito.internal.creation.settings.CreationSettings;
11import org.mockito.internal.handler.MockHandlerFactory;
12import org.mockito.internal.util.reflection.LenientCopyTool;
13import org.mockito.invocation.MockHandler;
14import org.mockito.mock.MockCreationSettings;
15import org.mockito.mock.MockName;
16import org.mockito.plugins.MockMaker;
17
18import java.lang.reflect.Modifier;
19
20@SuppressWarnings("unchecked")
21public class MockUtil {
22
23    private static final MockMaker mockMaker = ClassPathLoader.getMockMaker();
24
25    public boolean isTypeMockable(Class<?> type) {
26      return !type.isPrimitive() && !Modifier.isFinal(type.getModifiers());
27    }
28
29    public <T> T createMock(MockCreationSettings<T> settings) {
30        MockHandler mockHandler = new MockHandlerFactory().create(settings);
31
32        T mock = mockMaker.createMock(settings, mockHandler);
33
34        Object spiedInstance = settings.getSpiedInstance();
35        if (spiedInstance != null) {
36            new LenientCopyTool().copyToMock(spiedInstance, mock);
37        }
38
39        return mock;
40    }
41
42    public <T> void resetMock(T mock) {
43        InternalMockHandler oldHandler = (InternalMockHandler) getMockHandler(mock);
44        MockCreationSettings settings = oldHandler.getMockSettings();
45        MockHandler newHandler = new MockHandlerFactory().create(settings);
46
47        mockMaker.resetMock(mock, newHandler, settings);
48    }
49
50    public <T> InternalMockHandler<T> getMockHandler(T mock) {
51        if (mock == null) {
52            throw new NotAMockException("Argument should be a mock, but is null!");
53        }
54
55        if (isMockitoMock(mock)) {
56            return (InternalMockHandler) mockMaker.getHandler(mock);
57        } else {
58            throw new NotAMockException("Argument should be a mock, but is: " + mock.getClass());
59        }
60    }
61
62    public boolean isMock(Object mock) {
63        // double check to avoid classes that have the same interfaces, could be great to have a custom mockito field in the proxy instead of relying on instance fields
64        return mock instanceof MockitoMock && isMockitoMock(mock);
65    }
66
67    public boolean isSpy(Object mock) {
68        return mock instanceof MockitoSpy;
69    }
70
71    public boolean isMock(Class mockClass) {
72        return mockClass != null && MockitoMock.class.isAssignableFrom(mockClass);
73    }
74
75    public boolean isSpy(Class mockClass) {
76        return mockClass != null && MockitoSpy.class.isAssignableFrom(mockClass);
77    }
78
79    private <T> boolean isMockitoMock(T mock) {
80        return mockMaker.getHandler(mock) != null;
81    }
82
83    public MockName getMockName(Object mock) {
84        return getMockHandler(mock).getMockSettings().getMockName();
85    }
86
87    public void maybeRedefineMockName(Object mock, String newName) {
88        MockName mockName = getMockName(mock);
89        //TODO SF hacky...
90        if (mockName.isDefault() && getMockHandler(mock).getMockSettings() instanceof CreationSettings) {
91            ((CreationSettings) getMockHandler(mock).getMockSettings()).setMockName(new MockNameImpl(newName));
92        }
93    }
94
95    public MockCreationSettings getMockSettings(Object mock) {
96        return getMockHandler(mock).getMockSettings();
97    }
98}
99