• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / jmockit1 / 496

15 Nov 2025 05:33PM UTC coverage: 72.192% (-0.008%) from 72.2%
496

push

github

web-flow
Merge pull request #412 from hazendaz/renovate/major-spring-core

Update spring core to v7 (major)

5677 of 8360 branches covered (67.91%)

Branch coverage included in aggregate %.

11922 of 16018 relevant lines covered (74.43%)

0.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.41
/main/src/main/java/mockit/internal/expectations/PhasedExecutionState.java
1
/*
2
 * MIT License
3
 * Copyright (c) 2006-2025 JMockit developers
4
 * See LICENSE file for full license text.
5
 */
6
package mockit.internal.expectations;
7

8
import edu.umd.cs.findbugs.annotations.NonNull;
9
import edu.umd.cs.findbugs.annotations.Nullable;
10

11
import java.util.ArrayList;
12
import java.util.List;
13

14
import mockit.internal.expectations.invocation.ExpectedInvocation;
15
import mockit.internal.expectations.invocation.InvocationArguments;
16
import mockit.internal.state.TestRun;
17
import mockit.internal.util.GeneratedClasses;
18

19
final class PhasedExecutionState {
1✔
20
    @NonNull
21
    final List<Expectation> expectations;
22
    @NonNull
23
    final List<VerifiedExpectation> verifiedExpectations;
24
    @NonNull
25
    final EquivalentInstances equivalentInstances;
26
    @NonNull
27
    final InstanceBasedMatching instanceBasedMatching;
28
    @Nullable
29
    PartiallyMockedInstances partiallyMockedInstances;
30

31
    PhasedExecutionState() {
1✔
32
        expectations = new ArrayList<>();
1✔
33
        verifiedExpectations = new ArrayList<>();
1✔
34
        equivalentInstances = new EquivalentInstances();
1✔
35
        instanceBasedMatching = new InstanceBasedMatching();
1✔
36
    }
1✔
37

38
    void addExpectation(@NonNull Expectation expectation) {
39
        ExpectedInvocation invocation = expectation.invocation;
1✔
40
        forceMatchingOnMockInstanceIfRequired(invocation);
1✔
41
        removeMatchingExpectationsCreatedBefore(invocation);
1✔
42
        expectations.add(expectation);
1✔
43
    }
1✔
44

45
    private void forceMatchingOnMockInstanceIfRequired(@NonNull ExpectedInvocation invocation) {
46
        if (!invocation.matchInstance
1✔
47
                && isToBeMatchedOnInstance(invocation.instance, invocation.getMethodNameAndDescription())) {
1✔
48
            invocation.matchInstance = true;
1✔
49
        }
50
    }
1✔
51

52
    boolean isToBeMatchedOnInstance(@Nullable Object mock, @NonNull String mockNameAndDesc) {
53
        if (mock == null || mockNameAndDesc.charAt(0) == '<') {
1✔
54
            return false;
1✔
55
        }
56

57
        if (instanceBasedMatching.isToBeMatchedOnInstance(mock)
1✔
58
                || partiallyMockedInstances != null && partiallyMockedInstances.isToBeMatchedOnInstance(mock)) {
1✔
59
            return true;
1✔
60
        }
61

62
        return TestRun.getExecutingTest().isInjectableMock(mock);
1✔
63
    }
64

65
    private void removeMatchingExpectationsCreatedBefore(@NonNull ExpectedInvocation invocation) {
66
        Expectation previousExpectation = findPreviousExpectation(invocation);
1✔
67

68
        if (previousExpectation != null) {
1✔
69
            expectations.remove(previousExpectation);
1✔
70
            invocation.copyDefaultReturnValue(previousExpectation.invocation);
1✔
71
        }
72
    }
1✔
73

74
    @Nullable
75
    private Expectation findPreviousExpectation(@NonNull ExpectedInvocation newInvocation) {
76
        int n = expectations.size();
1✔
77

78
        if (n == 0) {
1✔
79
            return null;
1✔
80
        }
81

82
        Object mock = newInvocation.instance;
1✔
83
        @NonNull
84
        Boolean matchInstance = newInvocation.matchInstance;
1✔
85
        String mockClassDesc = newInvocation.getClassDesc();
1✔
86
        String mockNameAndDesc = newInvocation.getMethodNameAndDescription();
1✔
87
        boolean isConstructor = newInvocation.isConstructor();
1✔
88

89
        for (Expectation previous : expectations) {
1✔
90
            if (isMatchingInvocation(mock, matchInstance, mockClassDesc, mockNameAndDesc, isConstructor, previous)
1✔
91
                    && isWithMatchingArguments(newInvocation, previous.invocation)) {
1✔
92
                return previous;
1✔
93
            }
94
        }
1✔
95

96
        return null;
1✔
97
    }
98

99
    private boolean isMatchingInvocation(@Nullable Object mock, @Nullable Boolean matchInstance,
100
            @NonNull String mockClassDesc, @NonNull String mockNameAndDesc, boolean constructorInvocation,
101
            @NonNull Expectation expectation) {
102
        ExpectedInvocation invocation = expectation.invocation;
1✔
103

104
        return invocation.isMatch(mock, mockClassDesc, mockNameAndDesc) && isSameMockedClass(mock, invocation.instance)
1✔
105
                && (constructorInvocation || mock == null || isMatchingInstance(mock, matchInstance, expectation));
1✔
106
    }
107

108
    private static boolean isSameMockedClass(@Nullable Object mock1, @Nullable Object mock2) {
109
        if (mock1 == mock2) {
1✔
110
            return true;
1✔
111
        }
112

113
        if (mock1 != null && mock2 != null) {
1!
114
            Class<?> mockedClass1 = mock1.getClass();
1✔
115
            Class<?> mockedClass2 = GeneratedClasses.getMockedClass(mock2);
1✔
116
            return mockedClass2.isAssignableFrom(mockedClass1)
1✔
117
                    || TestRun.mockFixture().areCapturedClasses(mockedClass1, mockedClass2);
1✔
118
        }
119

120
        return false;
×
121
    }
122

123
    private boolean isWithMatchingArguments(@NonNull ExpectedInvocation newInvocation,
124
            @NonNull ExpectedInvocation previousInvocation) {
125
        InvocationArguments newArguments = newInvocation.arguments;
1✔
126
        InvocationArguments previousArguments = previousInvocation.arguments;
1✔
127

128
        if (newArguments.getMatchers() == null) {
1✔
129
            return previousArguments.isMatch(newArguments.getValues(), equivalentInstances.instanceMap);
1✔
130
        }
131

132
        return newArguments.hasEquivalentMatchers(previousArguments);
1✔
133
    }
134

135
    @Nullable
136
    Expectation findExpectation(@Nullable Object mock, @NonNull String mockClassDesc, @NonNull String mockNameAndDesc,
137
            @NonNull Object[] args) {
138
        boolean isConstructor = mockNameAndDesc.charAt(0) == '<';
1✔
139
        Expectation replayExpectationFound = null;
1✔
140

141
        // Note: new expectations might get added to the list, so a regular loop would cause a CME:
142
        // noinspection ForLoopReplaceableByForEach
143
        for (Expectation expectation : expectations) {
1✔
144
            if (replayExpectationFound != null && expectation.recordPhase == null) {
1✔
145
                continue;
1✔
146
            }
147

148
            if (isMatchingInvocation(mock, null, mockClassDesc, mockNameAndDesc, isConstructor, expectation)
1✔
149
                    && expectation.invocation.arguments.isMatch(args, equivalentInstances.instanceMap)) {
1✔
150
                if (expectation.recordPhase == null) {
1✔
151
                    replayExpectationFound = expectation;
1✔
152
                    continue;
1✔
153
                }
154

155
                if (isConstructor) {
1✔
156
                    equivalentInstances.registerReplacementInstanceIfApplicable(mock, expectation.invocation);
1✔
157
                }
158

159
                return expectation;
1✔
160
            }
161
        }
1✔
162

163
        return replayExpectationFound;
1✔
164
    }
165

166
    private boolean isMatchingInstance(@NonNull Object invokedInstance, @Nullable Boolean matchInstance,
167
            @NonNull Expectation expectation) {
168
        ExpectedInvocation invocation = expectation.invocation;
1✔
169
        Object invocationInstance = invocation.instance;
1✔
170
        assert invocationInstance != null;
1!
171

172
        if (equivalentInstances.isEquivalentInstance(invocationInstance, invokedInstance)) {
1✔
173
            return true;
1✔
174
        }
175

176
        if (TestRun.getExecutingTest().isInjectableMock(invokedInstance)
1✔
177
                || partiallyMockedInstances != null
178
                        && partiallyMockedInstances.isDynamicMockInstanceOrClass(invokedInstance, invocationInstance)
1!
179
                || equivalentInstances.areNonEquivalentInstances(invocationInstance, invokedInstance)) {
1✔
180
            return false;
1✔
181
        }
182

183
        return (matchInstance == null || !matchInstance) && !invocation.matchInstance && expectation.recordPhase != null
1✔
184
                && !equivalentInstances.replacementMap.containsValue(invocationInstance);
1!
185
    }
186
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc