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

hazendaz / jmockit1 / 548

29 Nov 2025 11:21PM UTC coverage: 72.124% (-0.08%) from 72.2%
548

Pull #424

github

hazendaz
[junit5] Add new annotation 'ExpectedException'

This annotation enables JUnit 5 tests to specify expected JMockit exceptions (such as MissingInvocation or UnexpectedInvocation or any other) directly on the test method, mirroring the JUnit 4 @test(expected = ...) pattern or ExpectedException rule usage. It simplifies migration of JMockit-based tests from JUnit 4 to JUnit 5, ensuring consistent exception verification for mocking scenarios.

For standard exception assertions unrelated to JMockit, users should continue to use JUnit 5’s assertThrows.

In beforeTestExecution, setup issues will trigger a TestAbortedException when expected match without failing test or attempting to run internals.

handle test execution exception and after test execution will check if expected exception and suppress the exception on match.

Expected exception message can be passed following junit 4 style of contains, if exact match is needed you can disable the messageContains flag
Pull Request #424: Introduction of 'ExpectedException' annotation

5687 of 8390 branches covered (67.78%)

Branch coverage included in aggregate %.

22 of 30 new or added lines in 1 file covered. (73.33%)

14 existing lines in 3 files now uncovered.

11938 of 16047 relevant lines covered (74.39%)

0.74 hits per line

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

82.57
/main/src/main/java/mockit/internal/util/StackTrace.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.util;
7

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

10
import java.io.IOException;
11

12
/**
13
 * Provides utility methods to extract and filter stack trace information.
14
 */
15
public final class StackTrace {
16
    @NonNull
17
    private final Throwable throwable;
18
    @NonNull
19
    private StackTraceElement[] elements;
20

21
    public StackTrace(@NonNull Throwable throwable) {
1✔
22
        this.throwable = throwable;
1✔
23
        elements = throwable.getStackTrace();
1✔
24
    }
1✔
25

26
    public int getDepth() {
27
        return elements.length;
1✔
28
    }
29

30
    @NonNull
31
    public StackTraceElement getElement(int index) {
32
        return elements[index];
1✔
33
    }
34

35
    public static void filterStackTrace(@NonNull Throwable t) {
36
        new StackTrace(t).filter();
1✔
37
    }
1✔
38

39
    public void filter() {
40
        StackTraceElement[] filteredST = new StackTraceElement[elements.length];
1✔
41
        int i = 0;
1✔
42

43
        for (StackTraceElement ste : elements) {
1✔
44
            if (ste.getFileName() != null) {
1✔
45
                String where = ste.getClassName();
1✔
46

47
                if (!isJDKOr3rdPartyLibraryInternalMethod(ste) && !isTestFrameworkMethod(where)
1✔
48
                        && !isJMockitMethod(where)) {
1✔
49
                    filteredST[i] = ste;
1✔
50
                    i++;
1✔
51
                }
52
            }
53
        }
54

55
        StackTraceElement[] newStackTrace = new StackTraceElement[i];
1✔
56
        System.arraycopy(filteredST, 0, newStackTrace, 0, i);
1✔
57
        throwable.setStackTrace(newStackTrace);
1✔
58
        elements = newStackTrace;
1✔
59

60
        Throwable cause = throwable.getCause();
1✔
61

62
        if (cause != null) {
1!
UNCOV
63
            new StackTrace(cause).filter();
×
64
        }
65
    }
1✔
66

67
    private static boolean isJDKOr3rdPartyLibraryInternalMethod(@NonNull StackTraceElement ste) {
68
        String className = ste.getClassName();
1✔
69

70
        return className.startsWith("sun.") && !ste.isNativeMethod() || className.startsWith("jdk.")
1!
71
                || className.startsWith("java.util.") || className.contains(".reflect.")
1✔
72
                || className.contains(".surefire.") || className.contains(".gradle.")
1!
73
                || className.contains(".intellij.") || className.contains(".jdt.");
1!
74
    }
75

76
    private static boolean isTestFrameworkMethod(@NonNull String where) {
77
        return where.startsWith("org.junit.") || where.startsWith("org.testng.");
1!
78
    }
79

80
    private static boolean isJMockitMethod(@NonNull String where) {
81
        if (!where.startsWith("mockit.")) {
1!
82
            return false;
×
83
        }
84

85
        int p = where.indexOf('$');
1✔
86

87
        if (p < 0) {
1✔
88
            int q = where.lastIndexOf("Test");
1✔
89
            return q < 0 || q + 4 < where.length();
1✔
90
        }
91

92
        int q = where.lastIndexOf("Test", p - 4);
1✔
93

94
        if (q < 0) {
1!
UNCOV
95
            return true;
×
96
        }
97

98
        q += 4;
1✔
99
        return q < where.length() && where.charAt(q) != '$';
1!
100
    }
101

102
    public void print(@NonNull Appendable output) {
103
        String previousFileName = null;
1✔
104
        int previousLineNumber = 0;
1✔
105
        String sep = "";
1✔
106

107
        for (int i = 0, d = getDepth(); i < d; i++) {
1✔
108
            StackTraceElement ste = elements[i];
1✔
109

110
            if (ste.getLineNumber() != previousLineNumber || !ste.getFileName().equals(previousFileName)) {
1!
111
                try {
112
                    output.append(sep).append("\tat ").append(ste.toString());
1✔
113
                } catch (IOException ignore) {
×
114
                }
1✔
115
                sep = "\n";
1✔
116
                previousFileName = ste.getFileName();
1✔
117
                previousLineNumber = ste.getLineNumber();
1✔
118
            }
119
        }
120
    }
1✔
121
}
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