Skip to content

Commit

Permalink
Add support for @FailsWith to assert errorMessage
Browse files Browse the repository at this point in the history
  • Loading branch information
leonard84 committed Dec 28, 2024
1 parent 230ad60 commit 72b4422
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/release_notes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ include::include.adoc[]
* Add `IStatelessAnnotationDrivenExtension` to allow a single extension instance to be reused across all specifications spockPull:2055[]
* Add new well-known versions to `Jvm` helper to support versions up to 29 spockPull:2057[]
** Built-in extensions have been updated to use this new interface where applicable.
* Add support for `@FailsWith` to assert exception message spockIssue:2039[]
* Improve `@Timeout` extension will now use virtual threads if available spockPull:1986[]
* Improve mock argument matching, types constraints or arguments in interactions can now handle primitive types like `_ as int` spockIssue:1974[]
* Improve `verifyEach` to accept an optional second index parameter for the assertion block closure spockPull:2043[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@

import org.spockframework.runtime.*;
import org.spockframework.runtime.extension.*;
import org.spockframework.runtime.model.TextPosition;

import spock.lang.FailsWith;

import java.util.Arrays;

/**
*
* @author Peter Niederwieser
Expand All @@ -44,7 +48,20 @@ public void intercept(IMethodInvocation invocation) throws Throwable {
}

private boolean checkException(Throwable t) {
if(matchesException(t)) {
if (!failsWith.expectedMessage().isEmpty() && !failsWith.expectedMessage().equals(t.getMessage())) {
throw new ConditionNotSatisfiedError(new Condition(
Arrays.asList(t, t.getMessage(), failsWith.expectedMessage()),
"e.value == expectedMessage",
TextPosition.create(-1, -1), null, null, null));
}
return true;
}
return false;
}

private boolean matchesException(Throwable t) {
return failsWith.value().isInstance(t)
|| (t instanceof ConditionFailedWithExceptionError && failsWith.value().isInstance(t.getCause()));
|| (t instanceof ConditionFailedWithExceptionError && failsWith.value().isInstance(t.getCause()));
}
}
9 changes: 9 additions & 0 deletions spock-core/src/main/java/spock/lang/FailsWith.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,13 @@
* @return the reason for the failure
*/
String reason() default "unknown";

/**
* The expected message of the exception.
* <p>
* If the value is empty, the message is not checked.
*
* @since 2.4
*/
String expectedMessage() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,24 @@ import org.spockframework.runtime.InvalidSpecException
import spock.lang.FailsWith
import spock.lang.Specification

import org.spockframework.runtime.SpockComparisonFailure

/**
*
* @author Peter Niederwieser
*/
class FailsWithOnMethod extends Specification {
class FailsWithOnMethod extends EmbeddedSpecification {
@FailsWith(IndexOutOfBoundsException)
def ex1() {
given:
def foo = []
foo.get(0)
}

@FailsWith(Exception)
@FailsWith(
value = Exception,
expectedMessage = "Index 0 out of bounds for length 0"
)
def ex2() {
given:
def foo = []
Expand All @@ -45,6 +50,33 @@ class FailsWithOnMethod extends Specification {
expect: true
}

def "@FailsWith can assert exception message"() {
when:
runner.runSpecBody """
@FailsWith(
value = Exception,
expectedMessage = "Index 1 out of bounds for length 1"
)
def foo() {
given:
def foo = []
foo.get(0)
}
"""

then:
SpockComparisonFailure e = thrown()
def expected = """Condition not satisfied:
e.value == expectedMessage
| | |
| | Index 1 out of bounds for length 1
| Index 0 out of bounds for length 0
java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0"""

e.message.startsWith(expected)

}

@FailsWith(ConditionFailedWithExceptionError)
def "can handle ConditionFailedWithExceptionError"() {
Expand Down Expand Up @@ -117,4 +149,3 @@ class MySpec extends Specification {
e.message == "@FailsWith needs to refer to an exception type, but does refer to 'java.util.List'"
}
}

0 comments on commit 72b4422

Please sign in to comment.