001 /*
002 * Created on Feb 7, 2008
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 *
014 * Copyright @2008-2009 the original author or authors.
015 */
016 package org.fest.test;
017
018 import static org.fest.util.Objects.areEqual;
019 import static org.fest.util.Strings.concat;
020 import static org.fest.util.Strings.quote;
021
022 /**
023 * Understands executing test code that is expected to fail.
024 *
025 * @author Alex Ruiz
026 * @author Yvonne Wang
027 */
028 public final class ExpectedFailure {
029
030 private final Class<? extends Throwable> errorType;
031
032 /**
033 * Specifies the expected failure message type.
034 * @param errorType the expected failure message type.
035 * @return a holder for the expected failure message type.
036 */
037 public static ExpectedFailure expect(Class<? extends Throwable> errorType) {
038 return new ExpectedFailure(errorType);
039 }
040
041 /**
042 * Specifies the expected message of an expected <code>{@link AssertionError}</code>.
043 * @param message the expected failure message.
044 * @return a holder of the expected failure message.
045 */
046 public static Message expectAssertionError(String message) {
047 return new ExpectedFailure(AssertionError.class).withMessage(message);
048 }
049
050 /**
051 * Specifies the expected failure message.
052 * @param message the expected failure message.
053 * @return a holder of the expected failure message.
054 */
055 public Message withMessage(String message) {
056 return new Message(errorType, message);
057 }
058
059 /**
060 * Understands executing test code that is expected to fail.
061 *
062 * @author Alex Ruiz
063 * @author Yvonne Wang
064 */
065 public static class Message {
066 private final Class<? extends Throwable> errorType;
067 private final String message;
068
069 Message(Class<? extends Throwable> errorType, String message) {
070 this.errorType = errorType;
071 this.message = message;
072 }
073
074 /**
075 * Executes the given code to test.
076 * @param codeToTest the code to test.
077 * @throws AssertionError if an exception of the expected type is never thrown by the code to test.
078 * @throws AssertionError if the type of the thrown exception is different than the expected type.
079 * @throws AssertionError if the message of the thrown exception is different than the expected message.
080 */
081 public void on(CodeToTest codeToTest) {
082 try {
083 codeToTest.run();
084 fail(concat("Expecting a thrown exception of type:<", errorTypeName(), ">"));
085 } catch (Throwable t) {
086 if (!errorType.isInstance(t))
087 fail(concat("Expecting exception of type:<", errorTypeName(), "> but was:<", t.getClass().getName(), ">"));
088 if (!areEqual(message, t.getMessage()))
089 fail(concat("Expecting message:<", quote(message), "> but was:<", quote(t.getMessage()), ">"));
090 }
091 }
092
093 private String errorTypeName() {
094 return errorType.getName();
095 }
096
097 private void fail(String failureMessage) {
098 throw new AssertionError(failureMessage);
099 }
100 }
101
102 private ExpectedFailure(Class<? extends Throwable> error) {
103 this.errorType = error;
104 }
105 }