001package org.junit.internal; 002 003import java.io.IOException; 004import java.io.ObjectOutputStream; 005 006import org.hamcrest.Description; 007import org.hamcrest.Matcher; 008import org.hamcrest.SelfDescribing; 009import org.hamcrest.StringDescription; 010 011/** 012 * An exception class used to implement <i>assumptions</i> (state in which a given test 013 * is meaningful and should or should not be executed). A test for which an assumption 014 * fails should not generate a test case failure. 015 * 016 * @see org.junit.Assume 017 */ 018public class AssumptionViolatedException extends RuntimeException implements SelfDescribing { 019 private static final long serialVersionUID = 2L; 020 021 /* 022 * We have to use the f prefix until the next major release to ensure 023 * serialization compatibility. 024 * See https://github.com/junit-team/junit4/issues/976 025 */ 026 private final String fAssumption; 027 private final boolean fValueMatcher; 028 private final Object fValue; 029 private final Matcher<?> fMatcher; 030 031 /** 032 * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead. 033 */ 034 @Deprecated 035 public AssumptionViolatedException(String assumption, boolean hasValue, Object value, Matcher<?> matcher) { 036 this.fAssumption = assumption; 037 this.fValue = value; 038 this.fMatcher = matcher; 039 this.fValueMatcher = hasValue; 040 041 if (value instanceof Throwable) { 042 initCause((Throwable) value); 043 } 044 } 045 046 /** 047 * An assumption exception with the given <i>value</i> (String or 048 * Throwable) and an additional failing {@link Matcher}. 049 * 050 * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead. 051 */ 052 @Deprecated 053 public AssumptionViolatedException(Object value, Matcher<?> matcher) { 054 this(null, true, value, matcher); 055 } 056 057 /** 058 * An assumption exception with the given <i>value</i> (String or 059 * Throwable) and an additional failing {@link Matcher}. 060 * 061 * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead. 062 */ 063 @Deprecated 064 public AssumptionViolatedException(String assumption, Object value, Matcher<?> matcher) { 065 this(assumption, true, value, matcher); 066 } 067 068 /** 069 * An assumption exception with the given message only. 070 * 071 * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead. 072 */ 073 @Deprecated 074 public AssumptionViolatedException(String assumption) { 075 this(assumption, false, null, null); 076 } 077 078 /** 079 * An assumption exception with the given message and a cause. 080 * 081 * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead. 082 */ 083 @Deprecated 084 public AssumptionViolatedException(String assumption, Throwable e) { 085 this(assumption, false, null, null); 086 initCause(e); 087 } 088 089 @Override 090 public String getMessage() { 091 return StringDescription.asString(this); 092 } 093 094 public void describeTo(Description description) { 095 if (fAssumption != null) { 096 description.appendText(fAssumption); 097 } 098 099 if (fValueMatcher) { 100 // a value was passed in when this instance was constructed; print it 101 if (fAssumption != null) { 102 description.appendText(": "); 103 } 104 105 description.appendText("got: "); 106 description.appendValue(fValue); 107 108 if (fMatcher != null) { 109 description.appendText(", expected: "); 110 description.appendDescriptionOf(fMatcher); 111 } 112 } 113 } 114 115 /** 116 * Override default Java object serialization to correctly deal with potentially unserializable matchers or values. 117 * By not implementing readObject, we assure ourselves of backwards compatibility and compatibility with the 118 * standard way of Java serialization. 119 * 120 * @param objectOutputStream The outputStream to write our representation to 121 * @throws IOException When serialization fails 122 */ 123 private void writeObject(ObjectOutputStream objectOutputStream) throws IOException { 124 ObjectOutputStream.PutField putField = objectOutputStream.putFields(); 125 putField.put("fAssumption", fAssumption); 126 putField.put("fValueMatcher", fValueMatcher); 127 128 // We have to wrap the matcher into a serializable form. 129 putField.put("fMatcher", SerializableMatcherDescription.asSerializableMatcher(fMatcher)); 130 131 // We have to wrap the value inside a non-String class (instead of serializing the String value directly) as 132 // A Description will handle a String and non-String object differently (1st is surrounded by '"' while the 133 // latter will be surrounded by '<' '>'. Wrapping it makes sure that the description of a serialized and 134 // non-serialized instance produce the exact same description 135 putField.put("fValue", SerializableValueDescription.asSerializableValue(fValue)); 136 137 objectOutputStream.writeFields(); 138 } 139}