• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.testng.internal;
2 
3 import org.testng.IExpectedExceptionsHolder;
4 import org.testng.ITestNGMethod;
5 import org.testng.TestException;
6 import org.testng.annotations.IExpectedExceptionsAnnotation;
7 import org.testng.annotations.ITestAnnotation;
8 import org.testng.internal.annotations.IAnnotationFinder;
9 
10 import java.util.Arrays;
11 
12 public class ExpectedExceptionsHolder {
13 
14   protected final IAnnotationFinder finder;
15   protected final ITestNGMethod method;
16   private final Class<?>[] expectedClasses;
17   private final IExpectedExceptionsHolder holder;
18 
ExpectedExceptionsHolder(IAnnotationFinder finder, ITestNGMethod method, IExpectedExceptionsHolder holder)19   protected ExpectedExceptionsHolder(IAnnotationFinder finder, ITestNGMethod method, IExpectedExceptionsHolder holder) {
20     this.finder = finder;
21     this.method = method;
22     expectedClasses = findExpectedClasses(finder, method);
23     this.holder = holder;
24   }
25 
findExpectedClasses(IAnnotationFinder finder, ITestNGMethod method)26   private static Class<?>[] findExpectedClasses(IAnnotationFinder finder, ITestNGMethod method) {
27     IExpectedExceptionsAnnotation expectedExceptions =
28         finder.findAnnotation(method, IExpectedExceptionsAnnotation.class);
29     // Old syntax
30     if (expectedExceptions != null) {
31       return expectedExceptions.getValue();
32     }
33 
34     // New syntax
35     ITestAnnotation testAnnotation = finder.findAnnotation(method, ITestAnnotation.class);
36     if (testAnnotation != null) {
37       return testAnnotation.getExpectedExceptions();
38     }
39 
40     return new Class<?>[0];
41   }
42 
43   /**
44    * @param ite The exception that was just thrown
45    * @return true if the exception that was just thrown is part of the
46    * expected exceptions
47    */
isExpectedException(Throwable ite)48   public boolean isExpectedException(Throwable ite) {
49     if (!hasExpectedClasses()) {
50       return false;
51     }
52 
53     // TestException is the wrapper exception that TestNG will be throwing when an exception was
54     // expected but not thrown
55     if (ite.getClass() == TestException.class) {
56       return false;
57     }
58 
59     Class<?> realExceptionClass= ite.getClass();
60 
61     for (Class<?> exception : expectedClasses) {
62       if (exception.isAssignableFrom(realExceptionClass) && holder.isThrowableMatching(ite)) {
63         return true;
64       }
65     }
66 
67     return false;
68   }
69 
wrongException(Throwable ite)70   public Throwable wrongException(Throwable ite) {
71     if (!hasExpectedClasses()) {
72       return ite;
73     }
74 
75     if (holder.isThrowableMatching(ite)) {
76       return new TestException("Expected exception of " +
77                                getExpectedExceptionsPluralize()
78                                + " but got " + ite, ite);
79     } else {
80       return new TestException(holder.getWrongExceptionMessage(ite), ite);
81     }
82   }
83 
noException(ITestNGMethod testMethod)84   public TestException noException(ITestNGMethod testMethod) {
85     if (!hasExpectedClasses()) {
86       return null;
87     }
88     return new TestException("Method " + testMethod + " should have thrown an exception of "
89                              + getExpectedExceptionsPluralize());
90   }
91 
hasExpectedClasses()92   private boolean hasExpectedClasses() {
93     return expectedClasses != null && expectedClasses.length > 0;
94   }
95 
getExpectedExceptionsPluralize()96   private String getExpectedExceptionsPluralize() {
97     StringBuilder sb = new StringBuilder();
98     if (expectedClasses.length > 1) {
99       sb.append("any of types ");
100       sb.append(Arrays.toString(expectedClasses));
101     } else {
102       sb.append("type ");
103       sb.append(expectedClasses[0]);
104     }
105     return sb.toString();
106   }
107 }
108